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