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