Subversion Repositories planix.SVN

Rev

Details | 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
struct Draw
8
{
9
	Point	deltas;
10
	Point	deltam;
11
	Memlayer		*dstlayer;
12
	Memimage	*src;
13
	Memimage	*mask;
14
	int	op;
15
};
16
 
17
static
18
void
19
ldrawop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave)
20
{
21
	struct Draw *d;
22
	Point p0, p1;
23
	Rectangle oclipr, srcr, r, mr;
24
	int ok;
25
 
26
	d = etc;
27
	if(insave && d->dstlayer->save==nil)
28
		return;
29
 
30
	p0 = addpt(screenr.min, d->deltas);
31
	p1 = addpt(screenr.min, d->deltam);
32
 
33
	if(insave){
34
		r = rectsubpt(screenr, d->dstlayer->delta);
35
		clipr = rectsubpt(clipr, d->dstlayer->delta);
36
	}else
37
		r = screenr;
38
 
39
	/* now in logical coordinates */
40
 
41
	/* clipr may have narrowed what we should draw on, so clip if necessary */
42
	if(!rectinrect(r, clipr)){
43
		oclipr = dst->clipr;
44
		dst->clipr = clipr;
45
		ok = drawclip(dst, &r, d->src, &p0, d->mask, &p1, &srcr, &mr);
46
		dst->clipr = oclipr;
47
		if(!ok)
48
			return;
49
	}
50
	memdraw(dst, r, d->src, p0, d->mask, p1, d->op);
51
}
52
 
53
void
54
memdraw(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1, int op)
55
{
56
	struct Draw d;
57
	Rectangle srcr, tr, mr;
58
	Memlayer *dl, *sl;
59
 
60
	if(drawdebug)
61
		iprint("memdraw %p %R %p %P %p %P\n", dst, r, src, p0, mask, p1);
62
 
63
	if(mask == nil)
64
		mask = memopaque;
65
 
66
	if(mask->layer){
67
if(drawdebug)	iprint("mask->layer != nil\n");
68
		return;	/* too hard, at least for now */
69
	}
70
 
71
    Top:
72
	if(dst->layer==nil && src->layer==nil){
73
		memimagedraw(dst, r, src, p0, mask, p1, op);
74
		return;
75
	}
76
 
77
	if(drawclip(dst, &r, src, &p0, mask, &p1, &srcr, &mr) == 0){
78
if(drawdebug)	iprint("drawclip dstcr %R srccr %R maskcr %R\n", dst->clipr, src->clipr, mask->clipr);
79
		return;
80
	}
81
 
82
	/*
83
 	 * Convert to screen coordinates.
84
	 */
85
	dl = dst->layer;
86
	if(dl != nil){
87
		r.min.x += dl->delta.x;
88
		r.min.y += dl->delta.y;
89
		r.max.x += dl->delta.x;
90
		r.max.y += dl->delta.y;
91
	}
92
    Clearlayer:
93
	if(dl!=nil && dl->clear){
94
		if(src == dst){
95
			p0.x += dl->delta.x;
96
			p0.y += dl->delta.y;
97
			src = dl->screen->image;
98
		}
99
		dst = dl->screen->image;
100
		goto Top;
101
	}
102
 
103
	sl = src->layer;
104
	if(sl != nil){
105
		p0.x += sl->delta.x;
106
		p0.y += sl->delta.y;
107
		srcr.min.x += sl->delta.x;
108
		srcr.min.y += sl->delta.y;
109
		srcr.max.x += sl->delta.x;
110
		srcr.max.y += sl->delta.y;
111
	}
112
 
113
	/*
114
	 * Now everything is in screen coordinates.
115
	 * mask is an image.  dst and src are images or obscured layers.
116
	 */
117
 
118
	/*
119
	 * if dst and src are the same layer, just draw in save area and expose.
120
	 */
121
	if(dl!=nil && dst==src){
122
		if(dl->save == nil)
123
			return;	/* refresh function makes this case unworkable */
124
		if(rectXrect(r, srcr)){
125
			tr = r;
126
			if(srcr.min.x < tr.min.x){
127
				p1.x += tr.min.x - srcr.min.x;
128
				tr.min.x = srcr.min.x;
129
			}
130
			if(srcr.min.y < tr.min.y){
131
				p1.y += tr.min.x - srcr.min.x;
132
				tr.min.y = srcr.min.y;
133
			}
134
			if(srcr.max.x > tr.max.x)
135
				tr.max.x = srcr.max.x;
136
			if(srcr.max.y > tr.max.y)
137
				tr.max.y = srcr.max.y;
138
			memlhide(dst, tr);
139
		}else{
140
			memlhide(dst, r);
141
			memlhide(dst, srcr);
142
		}
143
		memdraw(dl->save, rectsubpt(r, dl->delta), dl->save,
144
			subpt(srcr.min, src->layer->delta), mask, p1, op);
145
		memlexpose(dst, r);
146
		return;
147
	}
148
 
149
	if(sl){
150
		if(sl->clear){
151
			src = sl->screen->image;
152
			if(dl != nil){
153
				r.min.x -= dl->delta.x;
154
				r.min.y -= dl->delta.y;
155
				r.max.x -= dl->delta.x;
156
				r.max.y -= dl->delta.y;
157
			}
158
			goto Top;
159
		}
160
		/* relatively rare case; use save area */
161
		if(sl->save == nil)
162
			return;	/* refresh function makes this case unworkable */
163
		memlhide(src, srcr);
164
		/* convert back to logical coordinates */
165
		p0.x -= sl->delta.x;
166
		p0.y -= sl->delta.y;
167
		srcr.min.x -= sl->delta.x;
168
		srcr.min.y -= sl->delta.y;
169
		srcr.max.x -= sl->delta.x;
170
		srcr.max.y -= sl->delta.y;
171
		src = src->layer->save;
172
	}
173
 
174
	/*
175
	 * src is now an image.  dst may be an image or a clear layer
176
	 */
177
	if(dst->layer==nil)
178
		goto Top;
179
	if(dst->layer->clear)
180
		goto Clearlayer;
181
 
182
	/*
183
	 * dst is an obscured layer
184
	 */
185
	d.deltas = subpt(p0, r.min);
186
	d.deltam = subpt(p1, r.min);
187
	d.dstlayer = dl;
188
	d.src = src;
189
	d.op = op;
190
	d.mask = mask;
191
	_memlayerop(ldrawop, dst, r, r, &d);
192
}