Blame


1 76193d7c 2003-09-30 devnull #include <u.h>
2 76193d7c 2003-09-30 devnull #include <libc.h>
3 76193d7c 2003-09-30 devnull #include <draw.h>
4 76193d7c 2003-09-30 devnull #include <memdraw.h>
5 76193d7c 2003-09-30 devnull
6 76193d7c 2003-09-30 devnull /*
7 76193d7c 2003-09-30 devnull * elarc(dst,c,a,b,t,src,sp,alpha,phi)
8 76193d7c 2003-09-30 devnull * draws the part of an ellipse between rays at angles alpha and alpha+phi
9 76193d7c 2003-09-30 devnull * measured counterclockwise from the positive x axis. other
10 76193d7c 2003-09-30 devnull * arguments are as for ellipse(dst,c,a,b,t,src,sp)
11 76193d7c 2003-09-30 devnull */
12 76193d7c 2003-09-30 devnull
13 76193d7c 2003-09-30 devnull enum
14 76193d7c 2003-09-30 devnull {
15 76193d7c 2003-09-30 devnull R, T, L, B /* right, top, left, bottom */
16 76193d7c 2003-09-30 devnull };
17 76193d7c 2003-09-30 devnull
18 76193d7c 2003-09-30 devnull static
19 76193d7c 2003-09-30 devnull Point corners[] = {
20 76193d7c 2003-09-30 devnull {1,1},
21 76193d7c 2003-09-30 devnull {-1,1},
22 76193d7c 2003-09-30 devnull {-1,-1},
23 76193d7c 2003-09-30 devnull {1,-1}
24 76193d7c 2003-09-30 devnull };
25 76193d7c 2003-09-30 devnull
26 76193d7c 2003-09-30 devnull static
27 76193d7c 2003-09-30 devnull Point p00;
28 76193d7c 2003-09-30 devnull
29 76193d7c 2003-09-30 devnull /*
30 76193d7c 2003-09-30 devnull * make a "wedge" mask covering the desired angle and contained in
31 76193d7c 2003-09-30 devnull * a surrounding square; draw a full ellipse; intersect that with the
32 76193d7c 2003-09-30 devnull * wedge to make a mask through which to copy src to dst.
33 76193d7c 2003-09-30 devnull */
34 76193d7c 2003-09-30 devnull void
35 76193d7c 2003-09-30 devnull memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int alpha, int phi, int op)
36 76193d7c 2003-09-30 devnull {
37 76193d7c 2003-09-30 devnull int i, w, beta, tmp, c1, c2, m, m1;
38 76193d7c 2003-09-30 devnull Rectangle rect;
39 76193d7c 2003-09-30 devnull Point p, bnd[8];
40 76193d7c 2003-09-30 devnull Memimage *wedge, *figure, *mask;
41 76193d7c 2003-09-30 devnull
42 76193d7c 2003-09-30 devnull if(a < 0)
43 76193d7c 2003-09-30 devnull a = -a;
44 76193d7c 2003-09-30 devnull if(b < 0)
45 76193d7c 2003-09-30 devnull b = -b;
46 76193d7c 2003-09-30 devnull w = t;
47 76193d7c 2003-09-30 devnull if(w < 0)
48 76193d7c 2003-09-30 devnull w = 0;
49 76193d7c 2003-09-30 devnull alpha = -alpha; /* compensate for upside-down coords */
50 76193d7c 2003-09-30 devnull phi = -phi;
51 76193d7c 2003-09-30 devnull beta = alpha + phi;
52 76193d7c 2003-09-30 devnull if(phi < 0){
53 76193d7c 2003-09-30 devnull tmp = alpha;
54 76193d7c 2003-09-30 devnull alpha = beta;
55 76193d7c 2003-09-30 devnull beta = tmp;
56 76193d7c 2003-09-30 devnull phi = -phi;
57 76193d7c 2003-09-30 devnull }
58 76193d7c 2003-09-30 devnull if(phi >= 360){
59 76193d7c 2003-09-30 devnull memellipse(dst, c, a, b, t, src, sp, op);
60 76193d7c 2003-09-30 devnull return;
61 76193d7c 2003-09-30 devnull }
62 76193d7c 2003-09-30 devnull while(alpha < 0)
63 76193d7c 2003-09-30 devnull alpha += 360;
64 76193d7c 2003-09-30 devnull while(beta < 0)
65 76193d7c 2003-09-30 devnull beta += 360;
66 76193d7c 2003-09-30 devnull c1 = alpha/90 & 3; /* number of nearest corner */
67 76193d7c 2003-09-30 devnull c2 = beta/90 & 3;
68 76193d7c 2003-09-30 devnull /*
69 76193d7c 2003-09-30 devnull * icossin returns point at radius ICOSSCALE.
70 76193d7c 2003-09-30 devnull * multiplying by m1 moves it outside the ellipse
71 76193d7c 2003-09-30 devnull */
72 76193d7c 2003-09-30 devnull rect = Rect(-a-w, -b-w, a+w+1, b+w+1);
73 76193d7c 2003-09-30 devnull m = rect.max.x; /* inradius of bounding square */
74 76193d7c 2003-09-30 devnull if(m < rect.max.y)
75 76193d7c 2003-09-30 devnull m = rect.max.y;
76 76193d7c 2003-09-30 devnull m1 = (m+ICOSSCALE-1) >> 10;
77 76193d7c 2003-09-30 devnull m = m1 << 10; /* assure m1*cossin is inside */
78 76193d7c 2003-09-30 devnull i = 0;
79 76193d7c 2003-09-30 devnull bnd[i++] = Pt(0,0);
80 76193d7c 2003-09-30 devnull icossin(alpha, &p.x, &p.y);
81 76193d7c 2003-09-30 devnull bnd[i++] = mulpt(p, m1);
82 76193d7c 2003-09-30 devnull for(;;) {
83 76193d7c 2003-09-30 devnull bnd[i++] = mulpt(corners[c1], m);
84 76193d7c 2003-09-30 devnull if(c1==c2 && phi<180)
85 76193d7c 2003-09-30 devnull break;
86 76193d7c 2003-09-30 devnull c1 = (c1+1) & 3;
87 76193d7c 2003-09-30 devnull phi -= 90;
88 76193d7c 2003-09-30 devnull }
89 76193d7c 2003-09-30 devnull icossin(beta, &p.x, &p.y);
90 76193d7c 2003-09-30 devnull bnd[i++] = mulpt(p, m1);
91 76193d7c 2003-09-30 devnull
92 76193d7c 2003-09-30 devnull figure = nil;
93 76193d7c 2003-09-30 devnull mask = nil;
94 76193d7c 2003-09-30 devnull wedge = allocmemimage(rect, GREY1);
95 76193d7c 2003-09-30 devnull if(wedge == nil)
96 76193d7c 2003-09-30 devnull goto Return;
97 76193d7c 2003-09-30 devnull memfillcolor(wedge, DTransparent);
98 76193d7c 2003-09-30 devnull memfillpoly(wedge, bnd, i, ~0, memopaque, p00, S);
99 76193d7c 2003-09-30 devnull figure = allocmemimage(rect, GREY1);
100 76193d7c 2003-09-30 devnull if(figure == nil)
101 76193d7c 2003-09-30 devnull goto Return;
102 76193d7c 2003-09-30 devnull memfillcolor(figure, DTransparent);
103 76193d7c 2003-09-30 devnull memellipse(figure, p00, a, b, t, memopaque, p00, S);
104 76193d7c 2003-09-30 devnull mask = allocmemimage(rect, GREY1);
105 76193d7c 2003-09-30 devnull if(mask == nil)
106 76193d7c 2003-09-30 devnull goto Return;
107 76193d7c 2003-09-30 devnull memfillcolor(mask, DTransparent);
108 76193d7c 2003-09-30 devnull memimagedraw(mask, rect, figure, rect.min, wedge, rect.min, S);
109 76193d7c 2003-09-30 devnull c = subpt(c, dst->r.min);
110 76193d7c 2003-09-30 devnull memdraw(dst, dst->r, src, subpt(sp, c), mask, subpt(p00, c), op);
111 76193d7c 2003-09-30 devnull
112 76193d7c 2003-09-30 devnull Return:
113 76193d7c 2003-09-30 devnull freememimage(wedge);
114 76193d7c 2003-09-30 devnull freememimage(figure);
115 76193d7c 2003-09-30 devnull freememimage(mask);
116 76193d7c 2003-09-30 devnull }