vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | 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 }