1 #include "../lib9.h" 2 3 #include "../libdraw/draw.h" 4 #include "../libmemdraw/memdraw.h" 5 #include "../libmemlayer/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 }; 19 20 static void llineop(Memimage*, Rectangle, Rectangle, void*, int); 21 22 static 23 void 24 _memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr) 25 { 26 Rectangle r; 27 struct Lline ll; 28 Point d; 29 int srcclipped; 30 Memlayer *dl; 31 32 if(radius < 0) 33 return; 34 if(src->layer) /* can't draw line with layered source */ 35 return; 36 srcclipped = 0; 37 38 Top: 39 dl = dst->layer; 40 if(dl == nil){ 41 _memimageline(dst, p0, p1, end0, end1, radius, src, sp, clipr); 42 return; 43 } 44 if(!srcclipped){ 45 d = subpt(sp, p0); 46 if(rectclip(&clipr, rectsubpt(src->clipr, d)) == 0) 47 return; 48 if((src->flags&Frepl)==0 && rectclip(&clipr, rectsubpt(src->r, d))==0) 49 return; 50 srcclipped = 1; 51 } 52 53 /* dst is known to be a layer */ 54 p0.x += dl->delta.x; 55 p0.y += dl->delta.y; 56 p1.x += dl->delta.x; 57 p1.y += dl->delta.y; 58 clipr.min.x += dl->delta.x; 59 clipr.min.y += dl->delta.y; 60 clipr.max.x += dl->delta.x; 61 clipr.max.y += dl->delta.y; 62 if(dl->clear){ 63 dst = dst->layer->screen->image; 64 goto Top; 65 } 66 67 /* XXX */ 68 /* this is not the correct set of tests */ 69 /* 70 if(log2[dst->depth] != log2[src->depth] || log2[dst->depth]!=3) 71 return; 72 */ 73 74 /* can't use sutherland-cohen clipping because lines are wide */ 75 r = memlinebbox(p0, p1, end0, end1, radius); 76 /* 77 * r is now a bounding box for the line; 78 * use it as a clipping rectangle for subdivision 79 */ 80 if(rectclip(&r, clipr) == 0) 81 return; 82 ll.p0 = p0; 83 ll.p1 = p1; 84 ll.end0 = end0; 85 ll.end1 = end1; 86 ll.sp = sp; 87 ll.dstlayer = dst->layer; 88 ll.src = src; 89 ll.radius = radius; 90 ll.delta = dl->delta; 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); 116 } 117 118 void 119 memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp) 120 { 121 _memline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr); 122 } 123