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