line.c (2586B)
1 #include "u.h" 2 #include "lib.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 }