Blame


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