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