Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.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
}