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