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
struct Lline
8
{
9
	Point			p0;
10
	Point			p1;
11
	Point			delta;
12
	int			end0;
13
	int			end1;
14
	int			radius;
15
	Point			sp;
16
	Memlayer		*dstlayer;
17
	Memimage	*src;
18
	int			op;
19
};
20
 
21
static void llineop(Memimage*, Rectangle, Rectangle, void*, int);
22
 
23
static
24
void
25
_memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr, int op)
26
{
27
	Rectangle r;
28
	struct Lline ll;
29
	Point d;
30
	int srcclipped;
31
	Memlayer *dl;
32
 
33
	if(radius < 0)
34
		return;
35
	if(src->layer)	/* can't draw line with layered source */
36
		return;
37
	srcclipped = 0;
38
 
39
   Top:
40
	dl = dst->layer;
41
	if(dl == nil){
42
		_memimageline(dst, p0, p1, end0, end1, radius, src, sp, clipr, op);
43
		return;
44
	}
45
	if(!srcclipped){
46
		d = subpt(sp, p0);
47
		if(rectclip(&clipr, rectsubpt(src->clipr, d)) == 0)
48
			return;
49
		if((src->flags&Frepl)==0 && rectclip(&clipr, rectsubpt(src->r, d))==0)
50
			return;
51
		srcclipped = 1;
52
	}
53
 
54
	/* dst is known to be a layer */
55
	p0.x += dl->delta.x;
56
	p0.y += dl->delta.y;
57
	p1.x += dl->delta.x;
58
	p1.y += dl->delta.y;
59
	clipr.min.x += dl->delta.x;
60
	clipr.min.y += dl->delta.y;
61
	clipr.max.x += dl->delta.x;
62
	clipr.max.y += dl->delta.y;
63
	if(dl->clear){
64
		dst = dst->layer->screen->image;
65
		goto Top;
66
	}
67
 
68
	/* XXX */
69
	/* this is not the correct set of tests */
70
//	if(log2[dst->depth] != log2[src->depth] || log2[dst->depth]!=3)
71
//		return;
72
 
73
	/* can't use sutherland-cohen clipping because lines are wide */
74
	r = memlinebbox(p0, p1, end0, end1, radius);
75
	/*
76
	 * r is now a bounding box for the line;
77
	 * use it as a clipping rectangle for subdivision
78
	 */
79
	if(rectclip(&r, clipr) == 0)
80
		return;
81
	ll.p0 = p0;
82
	ll.p1 = p1;
83
	ll.end0 = end0;
84
	ll.end1 = end1;
85
	ll.sp = sp;
86
	ll.dstlayer = dst->layer;
87
	ll.src = src;
88
	ll.radius = radius;
89
	ll.delta = dl->delta;
90
	ll.op = op;
91
	_memlayerop(llineop, dst, r, r, &ll);
92
}
93
 
94
static
95
void
96
llineop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave)
97
{
98
	struct Lline *ll;
99
	Point p0, p1;
100
 
101
	USED(screenr.min.x);
102
	ll = etc;
103
	if(insave && ll->dstlayer->save==nil)
104
		return;
105
	if(!rectclip(&clipr, screenr))
106
		return;
107
	if(insave){
108
		p0 = subpt(ll->p0, ll->delta);
109
		p1 = subpt(ll->p1, ll->delta);
110
		clipr = rectsubpt(clipr, ll->delta);
111
	}else{
112
		p0 = ll->p0;
113
		p1 = ll->p1;
114
	}
115
	_memline(dst, p0, p1, ll->end0, ll->end1, ll->radius, ll->src, ll->sp, clipr, ll->op);
116
}
117
 
118
void
119
memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, int op)
120
{
121
	_memline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr, op);
122
}