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 #define RECUR(a,b,c,d) _layerop(fn, i, Rect(a.x, b.y, c.x, d.y), clipr, etc, front->layer->rear); 8*7dd7cddfSDavid du Colombier 9*7dd7cddfSDavid du Colombier static void 10*7dd7cddfSDavid du Colombier _layerop( 11*7dd7cddfSDavid du Colombier void (*fn)(Memimage*, Rectangle, Rectangle, void*, int), 12*7dd7cddfSDavid du Colombier Memimage *i, 13*7dd7cddfSDavid du Colombier Rectangle r, 14*7dd7cddfSDavid du Colombier Rectangle clipr, 15*7dd7cddfSDavid du Colombier void *etc, 16*7dd7cddfSDavid du Colombier Memimage *front) 17*7dd7cddfSDavid du Colombier { 18*7dd7cddfSDavid du Colombier Rectangle fr; 19*7dd7cddfSDavid du Colombier 20*7dd7cddfSDavid du Colombier Top: 21*7dd7cddfSDavid du Colombier if(front == i){ 22*7dd7cddfSDavid du Colombier /* no one is in front of this part of window; use the screen */ 23*7dd7cddfSDavid du Colombier fn(i->layer->screen->image, r, clipr, etc, 0); 24*7dd7cddfSDavid du Colombier return; 25*7dd7cddfSDavid du Colombier } 26*7dd7cddfSDavid du Colombier fr = front->layer->screenr; 27*7dd7cddfSDavid du Colombier if(rectXrect(r, fr) == 0){ 28*7dd7cddfSDavid du Colombier /* r doesn't touch this window; continue on next rearmost */ 29*7dd7cddfSDavid du Colombier front = front->layer->rear; 30*7dd7cddfSDavid du Colombier goto Top; 31*7dd7cddfSDavid du Colombier } 32*7dd7cddfSDavid du Colombier if(fr.max.y < r.max.y){ 33*7dd7cddfSDavid du Colombier RECUR(r.min, fr.max, r.max, r.max); 34*7dd7cddfSDavid du Colombier r.max.y = fr.max.y; 35*7dd7cddfSDavid du Colombier } 36*7dd7cddfSDavid du Colombier if(r.min.y < fr.min.y){ 37*7dd7cddfSDavid du Colombier RECUR(r.min, r.min, r.max, fr.min); 38*7dd7cddfSDavid du Colombier r.min.y = fr.min.y; 39*7dd7cddfSDavid du Colombier } 40*7dd7cddfSDavid du Colombier if(fr.max.x < r.max.x){ 41*7dd7cddfSDavid du Colombier RECUR(fr.max, r.min, r.max, r.max); 42*7dd7cddfSDavid du Colombier r.max.x = fr.max.x; 43*7dd7cddfSDavid du Colombier } 44*7dd7cddfSDavid du Colombier if(r.min.x < fr.min.x){ 45*7dd7cddfSDavid du Colombier RECUR(r.min, r.min, fr.min, r.max); 46*7dd7cddfSDavid du Colombier r.min.x = fr.min.x; 47*7dd7cddfSDavid du Colombier } 48*7dd7cddfSDavid du Colombier /* r is covered by front, so put in save area */ 49*7dd7cddfSDavid du Colombier (*fn)(i->layer->save, r, clipr, etc, 1); 50*7dd7cddfSDavid du Colombier } 51*7dd7cddfSDavid du Colombier 52*7dd7cddfSDavid du Colombier /* 53*7dd7cddfSDavid du Colombier * Assumes incoming rectangle has already been clipped to i's logical r and clipr 54*7dd7cddfSDavid du Colombier */ 55*7dd7cddfSDavid du Colombier void 56*7dd7cddfSDavid du Colombier memlayerop( 57*7dd7cddfSDavid du Colombier void (*fn)(Memimage*, Rectangle, Rectangle, void*, int), 58*7dd7cddfSDavid du Colombier Memimage *i, 59*7dd7cddfSDavid du Colombier Rectangle screenr, /* clipped to window boundaries */ 60*7dd7cddfSDavid du Colombier Rectangle clipr, /* clipped also to clipping rectangles of hierarchy */ 61*7dd7cddfSDavid du Colombier void *etc) 62*7dd7cddfSDavid du Colombier { 63*7dd7cddfSDavid du Colombier Memlayer *l; 64*7dd7cddfSDavid du Colombier Rectangle r, scr; 65*7dd7cddfSDavid du Colombier 66*7dd7cddfSDavid du Colombier l = i->layer; 67*7dd7cddfSDavid du Colombier if(!rectclip(&screenr, l->screenr)) 68*7dd7cddfSDavid du Colombier return; 69*7dd7cddfSDavid du Colombier if(l->clear){ 70*7dd7cddfSDavid du Colombier fn(l->screen->image, screenr, clipr, etc, 0); 71*7dd7cddfSDavid du Colombier return; 72*7dd7cddfSDavid du Colombier } 73*7dd7cddfSDavid du Colombier r = screenr; 74*7dd7cddfSDavid du Colombier scr = l->screen->image->clipr; 75*7dd7cddfSDavid du Colombier 76*7dd7cddfSDavid du Colombier /* 77*7dd7cddfSDavid du Colombier * Do the piece on the screen 78*7dd7cddfSDavid du Colombier */ 79*7dd7cddfSDavid du Colombier if(rectclip(&screenr, scr)) 80*7dd7cddfSDavid du Colombier _layerop(fn, i, screenr, clipr, etc, l->screen->frontmost); 81*7dd7cddfSDavid du Colombier if(rectinrect(r, scr)) 82*7dd7cddfSDavid du Colombier return; 83*7dd7cddfSDavid du Colombier 84*7dd7cddfSDavid du Colombier /* 85*7dd7cddfSDavid du Colombier * Do the piece off the screen 86*7dd7cddfSDavid du Colombier */ 87*7dd7cddfSDavid du Colombier if(!rectXrect(r, scr)){ 88*7dd7cddfSDavid du Colombier /* completely offscreen; easy */ 89*7dd7cddfSDavid du Colombier fn(l->save, r, clipr, etc, 1); 90*7dd7cddfSDavid du Colombier return; 91*7dd7cddfSDavid du Colombier } 92*7dd7cddfSDavid du Colombier if(r.min.y < scr.min.y){ 93*7dd7cddfSDavid du Colombier /* above screen */ 94*7dd7cddfSDavid du Colombier fn(l->save, Rect(r.min.x, r.min.y, r.max.x, scr.min.y), clipr, etc, 1); 95*7dd7cddfSDavid du Colombier r.min.y = scr.min.y; 96*7dd7cddfSDavid du Colombier } 97*7dd7cddfSDavid du Colombier if(r.max.y > scr.max.y){ 98*7dd7cddfSDavid du Colombier /* below screen */ 99*7dd7cddfSDavid du Colombier fn(l->save, Rect(r.min.x, scr.max.y, r.max.x, r.max.y), clipr, etc, 1); 100*7dd7cddfSDavid du Colombier r.max.y = scr.max.y; 101*7dd7cddfSDavid du Colombier } 102*7dd7cddfSDavid du Colombier if(r.min.x < scr.min.x){ 103*7dd7cddfSDavid du Colombier /* left of screen */ 104*7dd7cddfSDavid du Colombier fn(l->save, Rect(r.min.x, r.min.y, scr.min.x, r.max.y), clipr, etc, 1); 105*7dd7cddfSDavid du Colombier r.min.x = scr.min.x; 106*7dd7cddfSDavid du Colombier } 107*7dd7cddfSDavid du Colombier if(r.max.x > scr.max.x){ 108*7dd7cddfSDavid du Colombier /* right of screen */ 109*7dd7cddfSDavid du Colombier fn(l->save, Rect(scr.max.x, r.min.y, r.max.x, r.max.y), clipr, etc, 1); 110*7dd7cddfSDavid du Colombier } 111*7dd7cddfSDavid du Colombier } 112