Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <memdraw.h>
5 #include <memlayer.h>
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 };
21 static void llineop(Memimage*, Rectangle, Rectangle, void*, int);
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;
33 if(radius < 0)
34 return;
35 if(src->layer) /* can't draw line with layered source */
36 return;
37 srcclipped = 0;
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 }
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 }
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; */
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 }
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;
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;
115 _memline(dst, p0, p1, ll->end0, ll->end1, ll->radius, ll->src, ll->sp, clipr, ll->op);
118 void
119 memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, int op)
121 _memline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr, op);