Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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