1 #include "Painter.h"
2 #include "Fillers.h"
3 #include "AlphaBlend.h"
4
5 namespace Upp {
6
Start(int minx,int maxx)7 void SolidFiller::Start(int minx, int maxx)
8 {
9 t += minx;
10 }
11
InvertRGBA(const RGBA & c)12 inline RGBA InvertRGBA(const RGBA& c)
13 {
14 RGBA a;
15 a.r = ~c.r;
16 a.g = ~c.g;
17 a.b = ~c.b;
18 a.a = 255;
19 return a;
20 }
21
Render(int val)22 void SolidFiller::Render(int val)
23 {
24 AlphaBlend(t, invert ? InvertRGBA(*t) : c, val);
25 t++;
26 }
27
Render(int val,int len)28 void SolidFiller::Render(int val, int len)
29 {
30 if(val == 0) {
31 t += len;
32 return;
33 }
34 if(invert) {
35 RGBA *e = t + len;
36 if(val == 256)
37 while(t < e) {
38 *t = InvertRGBA(*t);
39 t++;
40 }
41 else
42 while(t < e) {
43 AlphaBlend(t, InvertRGBA(*t), val);
44 t++;
45 }
46 }
47 else {
48 if(((val - 256) | (c.a - 255)) == 0)
49 Fill(t, c, len);
50 else
51 AlphaBlend(t, c, val, len);
52 t += len;
53 }
54 }
55
Start(int minx,int maxx)56 void SubpixelFiller::Start(int minx, int maxx)
57 {
58 int x = minx / 3;
59 if(x > 0) {
60 begin = sbuffer;
61 x--;
62 }
63 else
64 begin = sbuffer + 3;
65 t += x;
66 sbuffer[0] = sbuffer[1] = sbuffer[2] = sbuffer[3] =
67 sbuffer[4] = sbuffer[5] = sbuffer[6] = sbuffer[7] = 0;
68 v = sbuffer + 3 + minx % 3;
69 if(ss) {
70 int xx = maxx / 3;
71 ss->Get(buffer, x, y, xx - x + 2);
72 s = buffer;
73 }
74 }
75
Render(int val)76 void SubpixelFiller::Render(int val)
77 {
78 int16 *w = v;
79 int h = val / 9;
80 int h2 = h + h;
81 w[-2] += h;
82 w[2] += h;
83 w[-1] += h2;
84 w[1] += h2;
85 w[0] += val - h2 - h2 - h2;
86 w[3] = 0;
87 v++;
88 }
89
RenderN(int val,int h,int n)90 void SubpixelFiller::RenderN(int val, int h, int n)
91 {
92 int16 *w = v;
93 int h2 = h + h;
94 int hv2 = val - h2 - h2;
95 int h3 = h2 + h;
96 int hh;
97 v += n;
98 switch(n) {
99 case 1:
100 w[-2] += h;
101 w[-1] += h2;
102 w[1] += h2;
103 w[0] += hv2 - h2;
104 w[2] += h;
105 w[3] = 0;
106 break;
107 case 2:
108 w[-2] += h;
109 w[3] = h;
110 w[-1] += h3;
111 w[2] += h3;
112 w[0] += hv2;
113 w[1] += hv2;
114 w[4] = 0;
115 break;
116 case 3:
117 w[-2] += h;
118 w[4] = h;
119 w[-1] += h3;
120 w[3] = h3;
121 hh = hv2 + h;
122 w[0] += hh;
123 w[2] += hh;
124 w[1] += hv2 + h2;
125 w[5] = 0;
126 break;
127 case 4:
128 w[-2] += h;
129 w[5] = h;
130 w[-1] += h3;
131 w[4] = h3;
132 hh = hv2 + h;
133 w[0] += hh;
134 w[3] = hh;
135 hh = hv2 + h3;
136 w[1] += hh;
137 w[2] += hh;
138 w[6] = 0;
139 break;
140 case 5:
141 w[-2] += h;
142 w[6] = h;
143 w[-1] += h3;
144 w[5] = h3;
145 hh = hv2 + h;
146 w[0] += hh;
147 w[4] = hh;
148 hh = h3 + hv2;
149 w[1] += hh;
150 w[3] = hh;
151 w[2] += h3 + hv2 + h;
152 w[7] = 0;
153 break;
154 case 6:
155 w[-2] += h;
156 w[7] = h;
157 w[-1] += h3;
158 w[6] = h3;
159 hh = hv2 + h;
160 w[0] += hh;
161 w[5] = hh;
162 hh = h3 + hv2;
163 w[1] += hh;
164 w[4] = hh;
165 hh = h3 + hv2 + h;
166 w[2] += hh;
167 w[3] = hh;
168 w[8] = 0;
169 break;
170 }
171 }
172
Render(int val,int len)173 void SubpixelFiller::Render(int val, int len)
174 {
175 int h = val / 9;
176 if(len > 6) {
177 int q = (3333333 - (v + 2 - begin)) % 3;
178 len -= q + 2;
179 int l = int(v + 2 + q - begin);
180 RenderN(val, h, q + 4);
181 Write(l / 3);
182 l = len / 3;
183 len -= 3 * l;
184 RGBA *e = min(t + l, end);
185 if(invert && !ss) {
186 if(val == 256)
187 while(t < e) {
188 *t = InvertRGBA(*t);
189 t++;
190 }
191 else
192 while(t < e) {
193 AlphaBlend(t, InvertRGBA(*t), val);
194 t++;
195 }
196 }
197 else {
198 if(val == 256)
199 if(!ss && color.a == 255) {
200 Fill(t, color, int(e - t));
201 t = e;
202 }
203 else
204 while(t < e)
205 AlphaBlend(t++, ss ? Mul8(*s++, alpha) : color);
206 else
207 if(ss)
208 while(t < e)
209 AlphaBlend(t++, Mul8(*s++, alpha), val);
210 else {
211 RGBA c = Mul8(color, val);
212 while(t < e)
213 AlphaBlend(t++, c);
214 }
215 }
216 v = begin = sbuffer + 3;
217 v[0] = h + h + h;
218 v[1] = h;
219 v[2] = 0;
220 }
221 RenderN(val, h, len);
222 }
223
Write(int len)224 void SubpixelFiller::Write(int len)
225 {
226 RGBA *e = min(t + len, end);
227 int16 *q = begin;
228 while(t < e) {
229 RGBA c = ss ? Mul8(*s++, alpha) : invert ? InvertRGBA(*t) : color;
230 int a;
231 if(t->a != 255)
232 AlphaBlend(t, c, (q[0] + q[1] + q[2]) / 3);
233 else
234 if(c.a == 255) {
235 t->r = (c.r * q[0] >> 8) + ((257 - q[0]) * t->r >> 8);
236 t->g = (c.g * q[1] >> 8) + ((257 - q[1]) * t->g >> 8);
237 t->b = (c.b * q[2] >> 8) + ((257 - q[2]) * t->b >> 8);
238 }
239 else {
240 a = c.a * q[0] >> 8;
241 t->r = (c.r * q[0] >> 8) + ((256 - a - (a >> 7)) * t->r >> 8);
242 a = c.a * q[1] >> 8;
243 t->g = (c.g * q[1] >> 8) + ((256 - a - (a >> 7)) * t->g >> 8);
244 a = c.a * q[2] >> 8;
245 t->b = (c.b * q[2] >> 8) + ((256 - a - (a >> 7)) * t->b >> 8);
246 }
247 t++;
248 q += 3;
249 }
250 }
251
End()252 void SubpixelFiller::End()
253 {
254 v[3] = v[4] = v[5] = 0;
255 Write(int(v + 3 - begin) / 3);
256 }
257
Start(int minx,int maxx)258 void SpanFiller::Start(int minx, int maxx)
259 {
260 t += minx;
261 ss->Get(buffer, minx, y, maxx - minx + 1);
262 s = buffer;
263 }
264
Render(int val)265 void SpanFiller::Render(int val)
266 {
267 if(alpha != 256)
268 val = alpha * val >> 8;
269 AlphaBlend(t++, *s++, val);
270 }
271
Render(int val,int len)272 void SpanFiller::Render(int val, int len)
273 {
274 if(val == 0) {
275 t += len;
276 s += len;
277 return;
278 }
279 if(alpha != 256)
280 val = alpha * val >> 8;
281 AlphaBlend(t, s, val, len);
282 t += len;
283 s += len;
284 }
285
Init(int _cx)286 void ClipFiller::Init(int _cx)
287 {
288 cx = _cx;
289 buffer.Alloc(2 * cx);
290 }
291
Clear()292 void ClipFiller::Clear()
293 {
294 t = ~buffer;
295 x = 0;
296 empty = true;
297 full = true;
298 last = -1;
299 }
300
Start(int xmin,int xmax)301 void ClipFiller::Start(int xmin, int xmax)
302 {
303 Render(0, xmin);
304 }
305
Span(int val,int len)306 void ClipFiller::Span(int val, int len)
307 {
308 int v = val >> 1;
309 if(last == val) {
310 int n = min(v + 128 - *lastn - 1, len);
311 *lastn += n;
312 len -= n;
313 }
314 last = -1;
315 while(len > 128) {
316 int n = min(len, 128);
317 *t++ = 0;
318 *t++ = v + n - 1;
319 len -= n;
320 }
321 if(len) {
322 *t++ = 0;
323 last = val;
324 lastn = t;
325 *t++ = v + len - 1;
326 }
327 }
328
Render(int val,int len)329 void ClipFiller::Render(int val, int len)
330 {
331 if(val == 256) {
332 Span(256, len);
333 empty = false;
334 }
335 else {
336 full = false;
337 if(val == 0)
338 Span(0, len);
339 else {
340 memset(t, val, len);
341 t += len;
342 empty = false;
343 last = -1;
344 }
345 }
346 x += len;
347 }
348
Render(int val)349 void ClipFiller::Render(int val)
350 {
351 Render(val, 1);
352 }
353
Finish(ClippingLine & cl)354 void ClipFiller::Finish(ClippingLine& cl)
355 {
356 if(empty)
357 return;
358 while(x < cx) {
359 int n = min(cx - x, 128);
360 *t++ = 0;
361 *t++ = n - 1;
362 x += n;
363 full = false;
364 }
365 ASSERT(t - ~buffer <= 2 * cx);
366 if(full)
367 cl.SetFull();
368 else
369 cl.Set(~buffer, int(t - ~buffer));
370 }
371
Render(int val)372 void MaskFillerFilter::Render(int val)
373 {
374 for(;;) {
375 if(empty) {
376 t->Render(0);
377 empty--;
378 return;
379 }
380 if(full) {
381 t->Render(val);
382 full--;
383 return;
384 }
385 byte m = *mask++;
386 if(m) {
387 t->Render(val * m >> 8);
388 return;
389 }
390 m = *mask++;
391 if(m < 128)
392 empty = m + 1;
393 else
394 full = m - 128 + 1;
395 }
396 }
397
Render(int val,int len)398 void MaskFillerFilter::Render(int val, int len)
399 {
400 while(len)
401 if(empty) {
402 int n = min(len, empty);
403 t->Render(0, n);
404 empty -= n;
405 len -= n;
406 }
407 else
408 if(full) {
409 int n = min(len, full);
410 t->Render(val, n);
411 full -= n;
412 len -= n;
413 }
414 else {
415 byte m = *mask++;
416 if(m) {
417 t->Render(val * m >> 8);
418 len--;
419 }
420 else {
421 m = *mask++;
422 if(m < 128)
423 empty = m + 1;
424 else
425 full = m - 128 + 1;
426 }
427 }
428 }
429
430 struct NilFiller : Rasterizer::Filler {
StartUpp::NilFiller431 void Start(int minx, int maxx) {}
RenderUpp::NilFiller432 void Render(int val, int len) {}
RenderUpp::NilFiller433 void Render(int val) {}
434 };
435
Start(int minx,int maxx)436 void MaskFillerFilter::Start(int minx, int maxx)
437 {
438 t->Start(minx, maxx);
439 Rasterizer::Filler *h = t;
440 NilFiller nil;
441 t = &nil;
442 Render(0, minx);
443 t = h;
444 }
445
Start(int minx,int maxx)446 void NoAAFillerFilter::Start(int minx, int maxx)
447 {
448 t->Start(minx, maxx);
449 }
450
Render(int val,int len)451 void NoAAFillerFilter::Render(int val, int len)
452 {
453 t->Render(val < 128 ? 0 : 256, len);
454 }
455
Render(int val)456 void NoAAFillerFilter::Render(int val)
457 {
458 t->Render(val < 128 ? 0 : 256);
459 }
460
461 }
462