Blame


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