Blame


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