draw.c (4063B)
1 #include "u.h" 2 #include "lib.h" 3 #include "draw.h" 4 #include "memdraw.h" 5 #include "memlayer.h" 6 7 struct Draw 8 { 9 Point deltas; 10 Point deltam; 11 Memlayer *dstlayer; 12 Memimage *src; 13 Memimage *mask; 14 int op; 15 }; 16 17 static 18 void 19 ldrawop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave) 20 { 21 struct Draw *d; 22 Point p0, p1; 23 Rectangle oclipr, srcr, r, mr; 24 int ok; 25 26 d = etc; 27 if(insave && d->dstlayer->save==nil) 28 return; 29 30 p0 = addpt(screenr.min, d->deltas); 31 p1 = addpt(screenr.min, d->deltam); 32 33 if(insave){ 34 r = rectsubpt(screenr, d->dstlayer->delta); 35 clipr = rectsubpt(clipr, d->dstlayer->delta); 36 }else 37 r = screenr; 38 39 /* now in logical coordinates */ 40 41 /* clipr may have narrowed what we should draw on, so clip if necessary */ 42 if(!rectinrect(r, clipr)){ 43 oclipr = dst->clipr; 44 dst->clipr = clipr; 45 ok = drawclip(dst, &r, d->src, &p0, d->mask, &p1, &srcr, &mr); 46 dst->clipr = oclipr; 47 if(!ok) 48 return; 49 } 50 memdraw(dst, r, d->src, p0, d->mask, p1, d->op); 51 } 52 53 void 54 memdraw(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1, int op) 55 { 56 struct Draw d; 57 Rectangle srcr, tr, mr; 58 Memlayer *dl, *sl; 59 60 if(drawdebug) 61 iprint("memdraw %p %R %p %P %p %P\n", dst, r, src, p0, mask, p1); 62 63 if(mask == nil) 64 mask = memopaque; 65 66 if(mask->layer){ 67 if(drawdebug) iprint("mask->layer != nil\n"); 68 return; /* too hard, at least for now */ 69 } 70 71 Top: 72 if(dst->layer==nil && src->layer==nil){ 73 memimagedraw(dst, r, src, p0, mask, p1, op); 74 return; 75 } 76 77 if(drawclip(dst, &r, src, &p0, mask, &p1, &srcr, &mr) == 0){ 78 if(drawdebug) iprint("drawclip dstcr %R srccr %R maskcr %R\n", dst->clipr, src->clipr, mask->clipr); 79 return; 80 } 81 82 /* 83 * Convert to screen coordinates. 84 */ 85 dl = dst->layer; 86 if(dl != nil){ 87 r.min.x += dl->delta.x; 88 r.min.y += dl->delta.y; 89 r.max.x += dl->delta.x; 90 r.max.y += dl->delta.y; 91 } 92 Clearlayer: 93 if(dl!=nil && dl->clear){ 94 if(src == dst){ 95 p0.x += dl->delta.x; 96 p0.y += dl->delta.y; 97 src = dl->screen->image; 98 } 99 dst = dl->screen->image; 100 goto Top; 101 } 102 103 sl = src->layer; 104 if(sl != nil){ 105 p0.x += sl->delta.x; 106 p0.y += sl->delta.y; 107 srcr.min.x += sl->delta.x; 108 srcr.min.y += sl->delta.y; 109 srcr.max.x += sl->delta.x; 110 srcr.max.y += sl->delta.y; 111 } 112 113 /* 114 * Now everything is in screen coordinates. 115 * mask is an image. dst and src are images or obscured layers. 116 */ 117 118 /* 119 * if dst and src are the same layer, just draw in save area and expose. 120 */ 121 if(dl!=nil && dst==src){ 122 if(dl->save == nil) 123 return; /* refresh function makes this case unworkable */ 124 if(rectXrect(r, srcr)){ 125 tr = r; 126 if(srcr.min.x < tr.min.x){ 127 p1.x += tr.min.x - srcr.min.x; 128 tr.min.x = srcr.min.x; 129 } 130 if(srcr.min.y < tr.min.y){ 131 p1.y += tr.min.x - srcr.min.x; 132 tr.min.y = srcr.min.y; 133 } 134 if(srcr.max.x > tr.max.x) 135 tr.max.x = srcr.max.x; 136 if(srcr.max.y > tr.max.y) 137 tr.max.y = srcr.max.y; 138 memlhide(dst, tr); 139 }else{ 140 memlhide(dst, r); 141 memlhide(dst, srcr); 142 } 143 memdraw(dl->save, rectsubpt(r, dl->delta), dl->save, 144 subpt(srcr.min, src->layer->delta), mask, p1, op); 145 memlexpose(dst, r); 146 return; 147 } 148 149 if(sl){ 150 if(sl->clear){ 151 src = sl->screen->image; 152 if(dl != nil){ 153 r.min.x -= dl->delta.x; 154 r.min.y -= dl->delta.y; 155 r.max.x -= dl->delta.x; 156 r.max.y -= dl->delta.y; 157 } 158 goto Top; 159 } 160 /* relatively rare case; use save area */ 161 if(sl->save == nil) 162 return; /* refresh function makes this case unworkable */ 163 memlhide(src, srcr); 164 /* convert back to logical coordinates */ 165 p0.x -= sl->delta.x; 166 p0.y -= sl->delta.y; 167 srcr.min.x -= sl->delta.x; 168 srcr.min.y -= sl->delta.y; 169 srcr.max.x -= sl->delta.x; 170 srcr.max.y -= sl->delta.y; 171 src = src->layer->save; 172 } 173 174 /* 175 * src is now an image. dst may be an image or a clear layer 176 */ 177 if(dst->layer==nil) 178 goto Top; 179 if(dst->layer->clear) 180 goto Clearlayer; 181 182 /* 183 * dst is an obscured layer 184 */ 185 d.deltas = subpt(p0, r.min); 186 d.deltam = subpt(p1, r.min); 187 d.dstlayer = dl; 188 d.src = src; 189 d.op = op; 190 d.mask = mask; 191 _memlayerop(ldrawop, dst, r, r, &d); 192 }