1 #include "mupdf/fitz.h"
2 
3 #include "draw-imp.h"
4 #include "glyph-imp.h"
5 #include "pixmap-imp.h"
6 
7 #include <string.h>
8 #include <assert.h>
9 
10 /*
11 
12 The functions in this file implement various flavours of Porter-Duff blending.
13 
14 We take the following as definitions:
15 
16 	Cx = Color (from plane x)
17 	ax = Alpha (from plane x)
18 	cx = Cx.ax = Premultiplied color (from plane x)
19 
20 The general PorterDuff blending equation is:
21 
22 	Blend Z = X op Y	cz = Fx.cx + Fy.cy	where Fx and Fy depend on op
23 
24 The two operations we use in this file are: '(X in Y) over Z' and
25 'S over Z'. The definitions of the 'over' and 'in' operations are as
26 follows:
27 
28 	For S over Z,	Fs = 1, Fz = 1-as
29 	For X in Y,	Fx = ay, Fy = 0
30 
31 We have 2 choices; we can either work with premultiplied data, or non
32 premultiplied data. Our
33 
34 First the premultiplied case:
35 
36 	Let S = (X in Y)
37 	Let R = (X in Y) over Z = S over Z
38 
39 	cs	= cx.Fx + cy.Fy	(where Fx = ay, Fy = 0)
40 		= cx.ay
41 	as	= ax.Fx + ay.Fy
42 		= ax.ay
43 
44 	cr	= cs.Fs + cz.Fz	(where Fs = 1, Fz = 1-as)
45 		= cs + cz.(1-as)
46 		= cx.ay + cz.(1-ax.ay)
47 	ar	= as.Fs + az.Fz
48 		= as + az.(1-as)
49 		= ax.ay + az.(1-ax.ay)
50 
51 This has various nice properties, like not needing any divisions, and
52 being symmetric in color and alpha, so this is what we use. Because we
53 went through the pain of deriving the non premultiplied forms, we list
54 them here too, though they are not used.
55 
56 Non Pre-multiplied case:
57 
58 	Cs.as	= Fx.Cx.ax + Fy.Cy.ay	(where Fx = ay, Fy = 0)
59 		= Cx.ay.ax
60 	Cs	= (Cx.ay.ax)/(ay.ax)
61 		= Cx
62 	Cr.ar	= Fs.Cs.as + Fz.Cz.az	(where Fs = 1, Fz = 1-as)
63 		= Cs.as	+ (1-as).Cz.az
64 		= Cx.ax.ay + Cz.az.(1-ax.ay)
65 	Cr	= (Cx.ax.ay + Cz.az.(1-ax.ay))/(ax.ay + az.(1-ax.ay))
66 
67 Much more complex, it seems. However, if we could restrict ourselves to
68 the case where we were always plotting onto an opaque background (i.e.
69 az = 1), then:
70 
71 	Cr	= Cx.(ax.ay) + Cz.(1-ax.ay)
72 		= (Cx-Cz)*(1-ax.ay) + Cz	(a single MLA operation)
73 	ar	= 1
74 
75 Sadly, this is not true in the general case, so we abandon this effort
76 and stick to using the premultiplied form.
77 
78 */
79 
80 typedef unsigned char byte;
81 
82 /* These are used by the non-aa scan converter */
83 
84 static inline void
template_solid_color_1_da(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da)85 template_solid_color_1_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da)
86 {
87 	int sa = FZ_EXPAND(color[1]);
88 	TRACK_FN();
89 	if (sa == 0)
90 		return;
91 	if (sa == 256)
92 	{
93 		do
94 		{
95 			dp[0] = color[0];
96 			dp[1] = 255;
97 			dp += 2;
98 		}
99 		while (--w);
100 	}
101 	else
102 	{
103 		do
104 		{
105 			dp[0] = FZ_BLEND(color[0], dp[0], sa);
106 			dp[1] = FZ_BLEND(255, dp[1], sa);
107 			dp += 2;
108 		}
109 		while (--w);
110 	}
111 }
112 
isbigendian(void)113 static inline int isbigendian(void)
114 {
115 	union { int i; char c[sizeof(int)]; } u = {1};
116 	return u.c[0] != 1;
117 }
118 
119 static inline void
template_solid_color_3_da(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da)120 template_solid_color_3_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da)
121 {
122 	unsigned int rgba = *(int *)color;
123 	int sa = FZ_EXPAND(color[3]);
124 	TRACK_FN();
125 	if (sa == 0)
126 		return;
127 	if (isbigendian())
128 		rgba |= 0x000000FF;
129 	else
130 		rgba |= 0xFF000000;
131 	if (sa == 256)
132 	{
133 		do
134 		{
135 			*(unsigned int *)dp = rgba;
136 			dp += 4;
137 		}
138 		while (--w);
139 	}
140 	else
141 	{
142 		unsigned int mask = 0xFF00FF00;
143 		unsigned int rb = rgba & (mask>>8);
144 		unsigned int ga = (rgba & mask)>>8;
145 		do
146 		{
147 			unsigned int RGBA = *(unsigned int *)dp;
148 			unsigned int RB = (RGBA<<8) & mask;
149 			unsigned int GA = RGBA & mask;
150 			RB += (rb-(RB>>8))*sa;
151 			GA += (ga-(GA>>8))*sa;
152 			RB &= mask;
153 			GA &= mask;
154 			*(unsigned int *)dp = (RB>>8) | GA;
155 			dp += 4;
156 		}
157 		while (--w);
158 	}
159 }
160 
161 static inline void
template_solid_color_4_da(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da)162 template_solid_color_4_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da)
163 {
164 	int sa = FZ_EXPAND(color[4]);
165 	TRACK_FN();
166 	if (sa == 0)
167 		return;
168 	if (sa == 256)
169 	{
170 #ifdef ARCH_UNALIGNED_OK
171 		if (w > 4)
172 		{
173 			if (isbigendian())
174 			{
175 				const uint32_t a = *(uint32_t*)color;
176 				const uint32_t b = 0xFF000000|(a>>8);
177 				const uint32_t c = 0x00FF0000|(a>>16)|(a<<24);
178 				const uint32_t d = 0x0000FF00|(a>>24)|(a<<16);
179 				const uint32_t e = 0x000000FF|(a<<8);
180 				w -= 3;
181 				do
182 				{
183 					((uint32_t *)(void *)dp)[0] = a;
184 					((uint32_t *)(void *)dp)[1] = b;
185 					((uint32_t *)(void *)dp)[2] = c;
186 					((uint32_t *)(void *)dp)[3] = d;
187 					((uint32_t *)(void *)dp)[4] = e;
188 					dp += 20;
189 					w -= 4;
190 				}
191 				while (w > 0);
192 			}
193 			else
194 			{
195 				const uint32_t a = *(uint32_t*)color;
196 				const uint32_t b = 0x000000FF|(a<<8);
197 				const uint32_t c = 0x0000FF00|(a<<16)|(a>>24);
198 				const uint32_t d = 0x00FF0000|(a<<24)|(a>>16);
199 				const uint32_t e = 0xFF000000|(a>>8);
200 				w -= 3;
201 				do
202 				{
203 					((uint32_t *)(void *)dp)[0] = a;
204 					((uint32_t *)(void *)dp)[1] = b;
205 					((uint32_t *)(void *)dp)[2] = c;
206 					((uint32_t *)(void *)dp)[3] = d;
207 					((uint32_t *)(void *)dp)[4] = e;
208 					dp += 20;
209 					w -= 4;
210 				}
211 				while (w > 0);
212 			}
213 			w += 3;
214 			if (w == 0)
215 				return;
216 		}
217 #endif
218 		do
219 		{
220 			dp[0] = color[0];
221 			dp[1] = color[1];
222 			dp[2] = color[2];
223 			dp[3] = color[3];
224 			dp[4] = 255;
225 			dp += 5;
226 		}
227 		while (--w);
228 	}
229 	else
230 	{
231 		do
232 		{
233 			dp[0] = FZ_BLEND(color[0], dp[0], sa);
234 			dp[1] = FZ_BLEND(color[1], dp[1], sa);
235 			dp[2] = FZ_BLEND(color[2], dp[2], sa);
236 			dp[3] = FZ_BLEND(color[3], dp[3], sa);
237 			dp[4] = FZ_BLEND(255, dp[5], sa);
238 			dp += 5;
239 		}
240 		while (--w);
241 	}
242 }
243 
244 static inline void
template_solid_color_N_256(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da)245 template_solid_color_N_256(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da)
246 {
247 	int k;
248 	int n1 = n - da;
249 	if (n == 3 && da == 0 && w >= 8)
250 	{
251 		union {uint32_t w[3]; byte b[12];} u;
252 
253 		u.b[0] = u.b[3] = u.b[6] = u.b[9] = color[0];
254 		u.b[1] = u.b[4] = u.b[7] = u.b[10] = color[1];
255 		u.b[2] = u.b[5] = u.b[8] = u.b[11] = color[2];
256 
257 		switch (((intptr_t)dp) & 3)
258 		{
259 		case 3:
260 			*dp++ = color[0];
261 			*(uint32_t *)dp = u.w[1];
262 			dp += 4;
263 			*(uint32_t *)dp = u.w[2];
264 			dp += 4;
265 			w -= 3;
266 			break;
267 		case 2:
268 			*dp++ = color[0];
269 			*dp++ = color[1];
270 			*(uint32_t *)dp = u.w[2];
271 			dp += 4;
272 			w -= 2;
273 			break;
274 		case 1:
275 			*dp++ = color[0];
276 			*dp++ = color[1];
277 			*dp++ = color[2];
278 			w -= 1;
279 			break;
280 		}
281 		w -= 4;
282 		do
283 		{
284 			*(uint32_t *)dp = u.w[0];
285 			dp += 4;
286 			*(uint32_t *)dp = u.w[1];
287 			dp += 4;
288 			*(uint32_t *)dp = u.w[2];
289 			dp += 4;
290 			w -= 4;
291 		}
292 		while (w > 0);
293 		w += 4;
294 		if (w == 0)
295 			return;
296 	}
297 	do
298 	{
299 		dp[0] = color[0];
300 		if (n1 > 1)
301 			dp[1] = color[1];
302 		if (n1 > 2)
303 			dp[2] = color[2];
304 		for (k = 3; k < n1; k++)
305 			dp[k] = color[k];
306 		if (da)
307 			dp[n1] = 255;
308 		dp += n;
309 	}
310 	while (--w);
311 }
312 
313 static inline void
template_solid_color_N_256_op(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)314 template_solid_color_N_256_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
315 {
316 	int k;
317 	int n1 = n - da;
318 	do
319 	{
320 		if (fz_overprint_component(eop, 0))
321 			dp[0] = color[0];
322 		if (n1 > 1)
323 			if (fz_overprint_component(eop, 1))
324 				dp[1] = color[1];
325 		if (n1 > 2)
326 			if (fz_overprint_component(eop, 2))
327 				dp[2] = color[2];
328 		for (k = 3; k < n1; k++)
329 			if (fz_overprint_component(eop, k))
330 				dp[k] = color[k];
331 		if (da)
332 			dp[n1] = 255;
333 		dp += n;
334 	}
335 	while (--w);
336 }
337 
338 static inline void
template_solid_color_N_sa(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,int sa)339 template_solid_color_N_sa(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa)
340 {
341 	int k;
342 	int n1 = n - da;
343 	do
344 	{
345 		for (k = 0; k < n1; k++)
346 			dp[k] = FZ_BLEND(color[k], dp[k], sa);
347 		if (da)
348 			dp[k] = FZ_BLEND(255, dp[k], sa);
349 		dp += n;
350 	}
351 	while (--w);
352 }
353 
354 static inline void
template_solid_color_N_sa_op(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,int sa,const fz_overprint * FZ_RESTRICT eop)355 template_solid_color_N_sa_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa, const fz_overprint * FZ_RESTRICT eop)
356 {
357 	int k;
358 	int n1 = n - da;
359 	do
360 	{
361 		for (k = 0; k < n1; k++)
362 			if (fz_overprint_component(eop, k))
363 				dp[k] = FZ_BLEND(color[k], dp[k], sa);
364 		if (da)
365 			dp[k] = FZ_BLEND(255, dp[k], sa);
366 		dp += n;
367 	}
368 	while (--w);
369 }
370 
371 #if FZ_PLOTTERS_N
372 static inline void
template_solid_color_N_general(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,int sa)373 template_solid_color_N_general(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa)
374 {
375 	int k;
376 	int n1 = n - da;
377 	if (sa == 256)
378 	{
379 		do
380 		{
381 			dp[0] = color[0];
382 			if (n1 > 1)
383 				dp[1] = color[1];
384 			if (n1 > 2)
385 				dp[2] = color[2];
386 			for (k = 3; k < n1; k++)
387 				dp[k] = color[k];
388 			if (da)
389 				dp[n1] = 255;
390 			dp += n;
391 		}
392 		while (--w);
393 	}
394 	else
395 	{
396 		do
397 		{
398 			for (k = 0; k < n1; k++)
399 				dp[k] = FZ_BLEND(color[k], dp[k], sa);
400 			if (da)
401 				dp[k] = FZ_BLEND(255, dp[k], sa);
402 			dp += n;
403 		}
404 		while (--w);
405 	}
406 }
407 
408 static inline void
template_solid_color_N_general_op(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,int sa,const fz_overprint * FZ_RESTRICT eop)409 template_solid_color_N_general_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa, const fz_overprint * FZ_RESTRICT eop)
410 {
411 	int k;
412 	int n1 = n - da;
413 	if (sa == 256)
414 	{
415 		do
416 		{
417 			if (fz_overprint_component(eop, 0))
418 				dp[0] = color[0];
419 			if (n1 > 1)
420 				if (fz_overprint_component(eop, 1))
421 					dp[1] = color[1];
422 			if (n1 > 2)
423 				if (fz_overprint_component(eop, 2))
424 					dp[2] = color[2];
425 			for (k = 3; k < n1; k++)
426 				if (fz_overprint_component(eop, k))
427 					dp[k] = color[k];
428 			if (da)
429 				dp[n1] = 255;
430 			dp += n;
431 		}
432 		while (--w);
433 	}
434 	else
435 	{
436 		do
437 		{
438 			for (k = 0; k < n1; k++)
439 				if (fz_overprint_component(eop, k))
440 					dp[k] = FZ_BLEND(color[k], dp[k], sa);
441 			if (da)
442 				dp[k] = FZ_BLEND(255, dp[k], sa);
443 			dp += n;
444 		}
445 		while (--w);
446 	}
447 }
448 #endif
449 
450 static inline void
template_solid_color_0_da(byte * FZ_RESTRICT dp,int w,int sa)451 template_solid_color_0_da(byte * FZ_RESTRICT dp, int w, int sa)
452 {
453 	if (sa == 256)
454 	{
455 		memset(dp, 255, w);
456 	}
457 	else
458 	{
459 		do
460 		{
461 			*dp = FZ_BLEND(255, *dp, sa);
462 			dp++;
463 		}
464 		while (--w);
465 	}
466 }
467 
468 #if FZ_PLOTTERS_G
paint_solid_color_1_alpha(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)469 static void paint_solid_color_1_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
470 {
471 	TRACK_FN();
472 	template_solid_color_N_sa(dp, 1, w, color, 0, FZ_EXPAND(color[1]));
473 }
474 
paint_solid_color_1(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)475 static void paint_solid_color_1(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
476 {
477 	TRACK_FN();
478 	template_solid_color_N_256(dp, 1, w, color, 0);
479 }
480 
paint_solid_color_1_da(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)481 static void paint_solid_color_1_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
482 {
483 	TRACK_FN();
484 	template_solid_color_1_da(dp, 2, w, color, 1);
485 }
486 #endif /* FZ_PLOTTERS_G */
487 
paint_solid_color_0_da(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)488 static void paint_solid_color_0_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
489 {
490 	TRACK_FN();
491 	template_solid_color_0_da(dp, w, 256);
492 }
493 
494 #if FZ_PLOTTERS_RGB
paint_solid_color_3_alpha(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)495 static void paint_solid_color_3_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
496 {
497 	TRACK_FN();
498 	template_solid_color_N_sa(dp, 3, w, color, 0, FZ_EXPAND(color[3]));
499 }
500 
paint_solid_color_3(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)501 static void paint_solid_color_3(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
502 {
503 	TRACK_FN();
504 	template_solid_color_N_256(dp, 3, w, color, 0);
505 }
506 
paint_solid_color_3_da(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)507 static void paint_solid_color_3_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
508 {
509 	TRACK_FN();
510 	template_solid_color_3_da(dp, 4, w, color, 1);
511 }
512 #endif /* FZ_PLOTTERS_RGB */
513 
514 #if FZ_PLOTTERS_CMYK
paint_solid_color_4_alpha(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)515 static void paint_solid_color_4_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
516 {
517 	TRACK_FN();
518 	template_solid_color_N_sa(dp, 4, w, color, 0, FZ_EXPAND(color[4]));
519 }
520 
paint_solid_color_4(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)521 static void paint_solid_color_4(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
522 {
523 	TRACK_FN();
524 	template_solid_color_N_256(dp, 4, w, color, 0);
525 }
526 
paint_solid_color_4_da(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)527 static void paint_solid_color_4_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
528 {
529 	TRACK_FN();
530 	template_solid_color_4_da(dp, 5, w, color, 1);
531 }
532 #endif /* FZ_PLOTTERS_CMYK */
533 
534 #if FZ_PLOTTERS_N
paint_solid_color_N_alpha(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)535 static void paint_solid_color_N_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
536 {
537 	TRACK_FN();
538 	template_solid_color_N_sa(dp, n, w, color, 0, FZ_EXPAND(color[n]));
539 }
540 
paint_solid_color_N(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)541 static void paint_solid_color_N(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
542 {
543 	TRACK_FN();
544 	template_solid_color_N_256(dp, n, w, color, 0);
545 }
546 
paint_solid_color_N_da(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)547 static void paint_solid_color_N_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
548 {
549 	TRACK_FN();
550 	template_solid_color_N_general(dp, n, w, color, 1, FZ_EXPAND(color[n-1]));
551 }
552 #endif /* FZ_PLOTTERS_N */
553 
554 #ifdef FZ_ENABLE_SPOT_RENDERING
paint_solid_color_N_alpha_op(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)555 static void paint_solid_color_N_alpha_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
556 {
557 	TRACK_FN();
558 	template_solid_color_N_sa_op(dp, n, w, color, 0, FZ_EXPAND(color[n]), eop);
559 }
560 
paint_solid_color_N_op(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)561 static void paint_solid_color_N_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
562 {
563 	TRACK_FN();
564 	template_solid_color_N_256_op(dp, n, w, color, 0, eop);
565 }
566 
paint_solid_color_N_da_op(byte * FZ_RESTRICT dp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)567 static void paint_solid_color_N_da_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
568 {
569 	TRACK_FN();
570 	template_solid_color_N_general_op(dp, n, w, color, 1, FZ_EXPAND(color[n-1]), eop);
571 }
572 #endif /* FZ_ENABLE_SPOT_RENDERING */
573 
574 fz_solid_color_painter_t *
fz_get_solid_color_painter(int n,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)575 fz_get_solid_color_painter(int n, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
576 {
577 #if FZ_ENABLE_SPOT_RENDERING
578 	if (fz_overprint_required(eop))
579 	{
580 		if (da)
581 			return paint_solid_color_N_da_op;
582 		else if (color[n] == 255)
583 			return paint_solid_color_N_op;
584 		else
585 			return paint_solid_color_N_alpha_op;
586 	}
587 #endif /* FZ_ENABLE_SPOT_RENDERING */
588 	switch (n-da)
589 	{
590 		case 0:
591 			return paint_solid_color_0_da;
592 #if FZ_PLOTTERS_G
593 		case 1:
594 			if (da)
595 				return paint_solid_color_1_da;
596 			else if (color[1] == 255)
597 				return paint_solid_color_1;
598 			else
599 				return paint_solid_color_1_alpha;
600 #endif /* FZ_PLOTTERS_G */
601 #if FZ_PLOTTERS_RGB
602 		case 3:
603 			if (da)
604 				return paint_solid_color_3_da;
605 			else if (color[3] == 255)
606 				return paint_solid_color_3;
607 			else
608 				return paint_solid_color_3_alpha;
609 #endif /* FZ_PLOTTERS_RGB */
610 #if FZ_PLOTTERS_CMYK
611 		case 4:
612 			if (da)
613 				return paint_solid_color_4_da;
614 			else if (color[4] == 255)
615 				return paint_solid_color_4;
616 			else
617 				return paint_solid_color_4_alpha;
618 #endif /* FZ_PLOTTERS_CMYK */
619 		default:
620 #if FZ_PLOTTERS_N
621 			if (da)
622 				return paint_solid_color_N_da;
623 			else if (color[n] == 255)
624 				return paint_solid_color_N;
625 			else
626 				return paint_solid_color_N_alpha;
627 #else
628 			return NULL;
629 #endif /* FZ_PLOTTERS_N */
630 	}
631 }
632 
633 /* Blend a non-premultiplied color in mask over destination */
634 
635 static inline void
template_span_with_color_1_da(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da)636 template_span_with_color_1_da(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
637 {
638 	int sa = FZ_EXPAND(color[1]);
639 	int g = color[0];
640 	if (sa == 256)
641 	{
642 		do
643 		{
644 			int ma = *mp++;
645 			ma = FZ_EXPAND(ma);
646 			if (ma == 256)
647 			{
648 				dp[0] = g;
649 				dp[1] = 255;
650 			}
651 			else if (ma != 0)
652 			{
653 				dp[0] = FZ_BLEND(g, dp[0], ma);
654 				dp[1] = FZ_BLEND(255, dp[1], ma);
655 			}
656 			dp += 2;
657 		}
658 		while (--w);
659 	}
660 	else
661 	{
662 		do
663 		{
664 			int ma = *mp++;
665 			ma = FZ_EXPAND(ma);
666 			if (ma != 0)
667 			{
668 				ma = FZ_COMBINE(ma, sa);
669 				dp[0] = FZ_BLEND(g, dp[0], ma);
670 				dp[1] = FZ_BLEND(255, dp[1], ma);
671 			}
672 			dp += 2;
673 		}
674 		while (--w);
675 	}
676 }
677 
678 static inline void
template_span_with_color_3_da(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da)679 template_span_with_color_3_da(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
680 {
681 	unsigned int rgba = *((const unsigned int *)color);
682 	unsigned int mask, rb, ga;
683 	int sa = FZ_EXPAND(color[3]);
684 	if (sa == 0)
685 		return;
686 	if (isbigendian())
687 		rgba |= 0x000000FF;
688 	else
689 		rgba |= 0xFF000000;
690 	mask = 0xFF00FF00;
691 	rb = rgba & (mask>>8);
692 	ga = (rgba & mask)>>8;
693 	if (sa == 256)
694 	{
695 		do
696 		{
697 			unsigned int ma = *mp++;
698 			dp += 4;
699 			ma = FZ_EXPAND(ma);
700 			if (ma == 256)
701 			{
702 				((unsigned int *)dp)[-1] = rgba;
703 			}
704 			else if (ma != 0)
705 			{
706 				unsigned int RGBA = ((unsigned int *)dp)[-1];
707 				unsigned int RB = (RGBA<<8) & mask;
708 				unsigned int GA = RGBA & mask;
709 				RB += (rb-(RB>>8))*ma;
710 				GA += (ga-(GA>>8))*ma;
711 				RB &= mask;
712 				GA &= mask;
713 				((unsigned int *)dp)[-1] = (RB>>8) | GA;
714 			}
715 		}
716 		while (--w);
717 	}
718 	else
719 	{
720 		do
721 		{
722 			unsigned int ma = *mp++;
723 			ma = FZ_COMBINE(FZ_EXPAND(ma), sa);
724 			dp += 4;
725 			if (ma != 0)
726  			{
727 				unsigned int RGBA = ((unsigned int*)dp)[-1];
728 				unsigned int RB = (RGBA<<8) & mask;
729 				unsigned int GA = RGBA & mask;
730 				RB += (rb-(RB>>8))*ma;
731 				GA += (ga-(GA>>8))*ma;
732 				RB &= mask;
733 				GA &= mask;
734 				((unsigned int *)dp)[-1] = (RB>>8) | GA;
735 			}
736 		}
737 		while (--w);
738 	}
739 }
740 
741 static inline void
template_span_with_color_4_da(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da)742 template_span_with_color_4_da(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
743 {
744 	int sa = FZ_EXPAND(color[4]);
745 	int c = color[0];
746 	int m = color[1];
747 	int y = color[2];
748 	int k = color[3];
749 	TRACK_FN();
750 	if (sa == 256)
751 	{
752 		do
753 		{
754 			int ma = *mp++;
755 			ma = FZ_EXPAND(ma);
756 			if (ma == 256)
757 			{
758 				dp[0] = c;
759 				dp[1] = m;
760 				dp[2] = y;
761 				dp[3] = k;
762 				dp[4] = 255;
763 			}
764 			else if (ma != 0)
765 			{
766 				dp[0] = FZ_BLEND(c, dp[0], ma);
767 				dp[1] = FZ_BLEND(m, dp[1], ma);
768 				dp[2] = FZ_BLEND(y, dp[2], ma);
769 				dp[3] = FZ_BLEND(k, dp[3], ma);
770 				dp[4] = FZ_BLEND(255, dp[4], ma);
771 			}
772 			dp += 5;
773 		}
774 		while (--w);
775 	}
776 	else
777 	{
778 		do
779 		{
780 			int ma = *mp++;
781 			ma = FZ_EXPAND(ma);
782 			if (ma != 0)
783 			{
784 				ma = FZ_COMBINE(ma, sa);
785 				dp[0] = FZ_BLEND(c, dp[0], ma);
786 				dp[1] = FZ_BLEND(m, dp[1], ma);
787 				dp[2] = FZ_BLEND(y, dp[2], ma);
788 				dp[3] = FZ_BLEND(k, dp[3], ma);
789 				dp[4] = FZ_BLEND(255, dp[4], ma);
790 			}
791 			dp += 5;
792 		}
793 		while (--w);
794 	}
795 }
796 
797 static inline void
template_span_with_color_N_general(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da)798 template_span_with_color_N_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da)
799 {
800 	int k;
801 	int n1 = n - da;
802 	int sa = FZ_EXPAND(color[n1]);
803 	if (sa == 0)
804 		return;
805 	if (sa == 256)
806 	{
807 		do
808 		{
809 			int ma = *mp++;
810 			ma = FZ_EXPAND(ma);
811 			if (ma == 256)
812 			{
813 				if (n1 > 0)
814 					dp[0] = color[0];
815 				if (n1 > 1)
816 					dp[1] = color[1];
817 				if (n1 > 2)
818 					dp[2] = color[2];
819 				for (k = 3; k < n1; k++)
820 					dp[k] = color[k];
821 				if (da)
822 					dp[n1] = 255;
823 			}
824 			else if (ma != 0)
825 			{
826 				for (k = 0; k < n1; k++)
827 					dp[k] = FZ_BLEND(color[k], dp[k], ma);
828 				if (da)
829 					dp[n1] = FZ_BLEND(255, dp[k], ma);
830 			}
831 			dp += n;
832 		}
833 		while (--w);
834 	}
835 	else
836 	{
837 		do
838 		{
839 			int ma = *mp++;
840 			ma = FZ_COMBINE(FZ_EXPAND(ma), sa);
841 			for (k = 0; k < n1; k++)
842 				dp[k] = FZ_BLEND(color[k], dp[k], ma);
843 			if (da)
844 				dp[k] = FZ_BLEND(255, dp[k], ma);
845 			dp += n;
846 		}
847 		while (--w);
848 	}
849 }
850 
851 static inline void
template_span_with_color_N_general_op(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)852 template_span_with_color_N_general_op(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
853 {
854 	int k;
855 	int n1 = n - da;
856 	int sa = FZ_EXPAND(color[n1]);
857 	if (sa == 0)
858 		return;
859 	if (sa == 256)
860 	{
861 		do
862 		{
863 			int ma = *mp++;
864 			ma = FZ_EXPAND(ma);
865 			if (ma == 256)
866 			{
867 				if (n1 > 0)
868 					if (fz_overprint_component(eop, 0))
869 						dp[0] = color[0];
870 				if (n1 > 1)
871 					if (fz_overprint_component(eop, 1))
872 						dp[1] = color[1];
873 				if (n1 > 2)
874 					if (fz_overprint_component(eop, 2))
875 						dp[2] = color[2];
876 				for (k = 3; k < n1; k++)
877 					if (fz_overprint_component(eop, k))
878 						dp[k] = color[k];
879 				if (da)
880 					dp[n1] = 255;
881 			}
882 			else if (ma != 0)
883 			{
884 				for (k = 0; k < n1; k++)
885 					if (fz_overprint_component(eop, k))
886 						dp[k] = FZ_BLEND(color[k], dp[k], ma);
887 				if (da)
888 					dp[n1] = FZ_BLEND(255, dp[k], ma);
889 			}
890 			dp += n;
891 		}
892 		while (--w);
893 	}
894 	else
895 	{
896 		do
897 		{
898 			int ma = *mp++;
899 			ma = FZ_COMBINE(FZ_EXPAND(ma), sa);
900 			for (k = 0; k < n1; k++)
901 				if (fz_overprint_component(eop, k))
902 					dp[k] = FZ_BLEND(color[k], dp[k], ma);
903 			if (da)
904 				dp[k] = FZ_BLEND(255, dp[k], ma);
905 			dp += n;
906 		}
907 		while (--w);
908 	}
909 }
910 
911 static void
paint_span_with_color_0_da(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)912 paint_span_with_color_0_da(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
913 {
914 	TRACK_FN();
915 	template_span_with_color_N_general(dp, mp, 1, w, color, 1);
916 }
917 
918 static void
paint_span_with_color_1(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)919 paint_span_with_color_1(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
920 {
921 	TRACK_FN();
922 	template_span_with_color_N_general(dp, mp, 1, w, color, 0);
923 }
924 
925 static void
paint_span_with_color_1_da(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)926 paint_span_with_color_1_da(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
927 {
928 	TRACK_FN();
929 	template_span_with_color_1_da(dp, mp, 2, w, color, 1);
930 }
931 
932 #if FZ_PLOTTERS_RGB
933 static void
paint_span_with_color_3(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)934 paint_span_with_color_3(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
935 {
936 	TRACK_FN();
937 	template_span_with_color_N_general(dp, mp, 3, w, color, 0);
938 }
939 
940 static void
paint_span_with_color_3_da(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)941 paint_span_with_color_3_da(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
942 {
943 	TRACK_FN();
944 	template_span_with_color_3_da(dp, mp, 4, w, color, 1);
945 }
946 #endif /* FZ_PLOTTERS_RGB */
947 
948 #if FZ_PLOTTERS_CMYK
949 static void
paint_span_with_color_4(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)950 paint_span_with_color_4(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
951 {
952 	TRACK_FN();
953 	template_span_with_color_N_general(dp, mp, 4, w, color, 0);
954 }
955 
956 static void
paint_span_with_color_4_da(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)957 paint_span_with_color_4_da(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
958 {
959 	TRACK_FN();
960 	template_span_with_color_4_da(dp, mp, 5, w, color, 1);
961 }
962 #endif /* FZ_PLOTTERS_CMYK */
963 
964 #if FZ_PLOTTERS_N
965 static void
paint_span_with_color_N(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)966 paint_span_with_color_N(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
967 {
968 	TRACK_FN();
969 	template_span_with_color_N_general(dp, mp, n, w, color, 0);
970 }
971 
972 static void
paint_span_with_color_N_da(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)973 paint_span_with_color_N_da(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
974 {
975 	TRACK_FN();
976 	template_span_with_color_N_general(dp, mp, n, w, color, 1);
977 }
978 #endif /* FZ_PLOTTERS_N */
979 
980 #ifdef FZ_ENABLE_SPOT_RENDERING
981 static void
paint_span_with_color_N_op(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)982 paint_span_with_color_N_op(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
983 {
984 	TRACK_FN();
985 	template_span_with_color_N_general_op(dp, mp, n, w, color, 0, eop);
986 }
987 
988 static void
paint_span_with_color_N_da_op(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT mp,int n,int w,const byte * FZ_RESTRICT color,int da,const fz_overprint * FZ_RESTRICT eop)989 paint_span_with_color_N_da_op(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop)
990 {
991 	TRACK_FN();
992 	template_span_with_color_N_general_op(dp, mp, n, w, color, 1, eop);
993 }
994 #endif /* FZ_ENABLE_SPOT_RENDERING */
995 
996 fz_span_color_painter_t *
fz_get_span_color_painter(int n,int da,const byte * FZ_RESTRICT color,const fz_overprint * FZ_RESTRICT eop)997 fz_get_span_color_painter(int n, int da, const byte * FZ_RESTRICT color, const fz_overprint * FZ_RESTRICT eop)
998 {
999 #if FZ_ENABLE_SPOT_RENDERING
1000 	if (fz_overprint_required(eop))
1001 	{
1002 		return da ? paint_span_with_color_N_da_op : paint_span_with_color_N_op;
1003 	}
1004 #endif /* FZ_ENABLE_SPOT_RENDERING */
1005 	switch(n-da)
1006 	{
1007 	case 0: return da ? paint_span_with_color_0_da : NULL;
1008 	case 1: return da ? paint_span_with_color_1_da : paint_span_with_color_1;
1009 #if FZ_PLOTTERS_RGB
1010 	case 3: return da ? paint_span_with_color_3_da : paint_span_with_color_3;
1011 #endif/* FZ_PLOTTERS_RGB */
1012 #if FZ_PLOTTERS_CMYK
1013 	case 4: return da ? paint_span_with_color_4_da : paint_span_with_color_4;
1014 #endif/* FZ_PLOTTERS_CMYK */
1015 #if FZ_PLOTTERS_N
1016 	default: return da ? paint_span_with_color_N_da : paint_span_with_color_N;
1017 #else
1018 	default: return NULL;
1019 #endif /* FZ_PLOTTERS_N */
1020 	}
1021 }
1022 
1023 /* Blend source in mask over destination */
1024 
1025 /* FIXME: There is potential for SWAR optimisation here */
1026 static inline void
template_span_with_mask_1_general(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,int a,const byte * FZ_RESTRICT mp,int w)1027 template_span_with_mask_1_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int w)
1028 {
1029 	do
1030 	{
1031 		int ma = *mp++;
1032 		ma = FZ_EXPAND(ma);
1033 		if (ma == 0 || (a && sp[1] == 0))
1034 		{
1035 			dp += 1 + a;
1036 			sp += 1 + a;
1037 		}
1038 		else if (ma == 256)
1039 		{
1040 			*dp++ = *sp++;
1041 			if (a)
1042 				*dp++ = *sp++;
1043 		}
1044 		else
1045 		{
1046 			*dp = FZ_BLEND(*sp, *dp, ma);
1047 			sp++; dp++;
1048 			if (a)
1049 			{
1050 				*dp = FZ_BLEND(*sp, *dp, ma);
1051 				sp++; dp++;
1052 			}
1053 		}
1054 	}
1055 	while (--w);
1056 }
1057 
1058 static inline void
template_span_with_mask_3_general(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,int a,const byte * FZ_RESTRICT mp,int w)1059 template_span_with_mask_3_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int w)
1060 {
1061 	do
1062 	{
1063 		int ma = *mp++;
1064 		ma = FZ_EXPAND(ma);
1065 		if (ma == 0 || (a && sp[3] == 0))
1066 		{
1067 			dp += 3 + a;
1068 			sp += 3 + a;
1069 		}
1070 		else if (ma == 256)
1071 		{
1072 			if (a)
1073 			{
1074 				*(int32_t *)dp = *(int32_t *)sp;
1075 				sp += 4; dp += 4;
1076 			}
1077 			else
1078 			{
1079 				*dp++ = *sp++;
1080 				*dp++ = *sp++;
1081 				*dp++ = *sp++;
1082 			}
1083 		}
1084 		else if (a)
1085 		{
1086 			const uint32_t mask = 0x00ff00ff;
1087 			uint32_t d0 = *(uint32_t *)dp;
1088 			uint32_t d1 = d0>>8;
1089 			uint32_t s0 = *(uint32_t *)sp;
1090 			uint32_t s1 = s0>>8;
1091 			d0 &= mask;
1092 			d1 &= mask;
1093 			s0 &= mask;
1094 			s1 &= mask;
1095 			d0 = (((d0<<8) + (s0-d0)*ma)>>8) & mask;
1096 			d1 = ((d1<<8) + (s1-d1)*ma) & ~mask;
1097 			d0 |= d1;
1098 			assert((d0>>24) >= (d0 & 0xff));
1099 			assert((d0>>24) >= ((d0>>8) & 0xff));
1100 			assert((d0>>24) >= ((d0>>16) & 0xff));
1101 			*(uint32_t *)dp = d0;
1102 			sp += 4;
1103 			dp += 4;
1104 		}
1105 		else
1106 		{
1107 			*dp = FZ_BLEND(*sp, *dp, ma);
1108 			sp++; dp++;
1109 			*dp = FZ_BLEND(*sp, *dp, ma);
1110 			sp++; dp++;
1111 			*dp = FZ_BLEND(*sp, *dp, ma);
1112 			sp++; dp++;
1113 		}
1114 	}
1115 	while (--w);
1116 }
1117 
1118 static inline void
template_span_with_mask_4_general(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,int a,const byte * FZ_RESTRICT mp,int w)1119 template_span_with_mask_4_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int w)
1120 {
1121 	do
1122 	{
1123 		int ma = *mp++;
1124 		ma = FZ_EXPAND(ma);
1125 		if (ma == 0 || (a && sp[4] == 0))
1126 		{
1127 			dp += 4 + a;
1128 			sp += 4 + a;
1129 		}
1130 		else if (ma == 256)
1131 		{
1132 			if (!a)
1133 			{
1134 				*(uint32_t *)dp = *(uint32_t *)sp;
1135 				dp += 4;
1136 				sp += 4;
1137 			}
1138 			else
1139 			{
1140 				*dp++ = *sp++;
1141 				*dp++ = *sp++;
1142 				*dp++ = *sp++;
1143 				*dp++ = *sp++;
1144 				*dp++ = *sp++;
1145 			}
1146 		}
1147 		else if (a)
1148 		{
1149 			*dp = FZ_BLEND(*sp, *dp, ma);
1150 			sp++; dp++;
1151 			*dp = FZ_BLEND(*sp, *dp, ma);
1152 			sp++; dp++;
1153 			*dp = FZ_BLEND(*sp, *dp, ma);
1154 			sp++; dp++;
1155 			*dp = FZ_BLEND(*sp, *dp, ma);
1156 			sp++; dp++;
1157 			*dp = FZ_BLEND(*sp, *dp, ma);
1158 			sp++; dp++;
1159 		}
1160 		else
1161 		{
1162 			const uint32_t mask = 0x00ff00ff;
1163 			uint32_t d0 = *(uint32_t *)dp;
1164 			uint32_t d1 = d0>>8;
1165 			uint32_t s0 = *(uint32_t *)sp;
1166 			uint32_t s1 = s0>>8;
1167 			sp += 4;
1168 			d0 &= mask;
1169 			d1 &= mask;
1170 			s0 &= mask;
1171 			s1 &= mask;
1172 			d0 = (((d0<<8) + (s0-d0)*ma)>>8) & mask;
1173 			d1 = ((d1<<8) + (s1-d1)*ma) & ~mask;
1174 			d0 |= d1;
1175 			*(uint32_t *)dp = d0;
1176 			dp += 4;
1177 		}
1178 	}
1179 	while (--w);
1180 }
1181 
1182 static inline void
template_span_with_mask_N_general(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,int a,const byte * FZ_RESTRICT mp,int n,int w)1183 template_span_with_mask_N_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int n, int w)
1184 {
1185 	do
1186 	{
1187 		int ma = *mp++;
1188 		ma = FZ_EXPAND(ma);
1189 		if (ma == 0 || (a && sp[n] == 0))
1190 		{
1191 			dp += n + a;
1192 			sp += n + a;
1193 		}
1194 		else if (ma == 256)
1195 		{
1196 			int k;
1197 			for (k = 0; k < n; k++)
1198 				*dp++ = *sp++;
1199 			if (a)
1200 				*dp++ = *sp++;
1201 		}
1202 		else
1203 		{
1204 			int k;
1205 			for (k = 0; k < n; k++)
1206 			{
1207 				*dp = FZ_BLEND(*sp, *dp, ma);
1208 				sp++; dp++;
1209 			}
1210 			if (a)
1211 			{
1212 				*dp = FZ_BLEND(*sp, *dp, ma);
1213 				sp++; dp++;
1214 			}
1215 		}
1216 	}
1217 	while (--w);
1218 }
1219 
1220 static void
paint_span_with_mask_0_a(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,const byte * FZ_RESTRICT mp,int w,int n,int a,const fz_overprint * FZ_RESTRICT eop)1221 paint_span_with_mask_0_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
1222 {
1223 	TRACK_FN();
1224 	template_span_with_mask_N_general(dp, sp, 1, mp, 0, w);
1225 }
1226 
1227 static void
paint_span_with_mask_1_a(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,const byte * FZ_RESTRICT mp,int w,int n,int a,const fz_overprint * FZ_RESTRICT eop)1228 paint_span_with_mask_1_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
1229 {
1230 	TRACK_FN();
1231 	template_span_with_mask_1_general(dp, sp, 1, mp, w);
1232 }
1233 
1234 static void
paint_span_with_mask_1(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,const byte * FZ_RESTRICT mp,int w,int n,int a,const fz_overprint * FZ_RESTRICT eop)1235 paint_span_with_mask_1(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
1236 {
1237 	TRACK_FN();
1238 	template_span_with_mask_1_general(dp, sp, 0, mp, w);
1239 }
1240 
1241 #if FZ_PLOTTERS_RGB
1242 static void
paint_span_with_mask_3_a(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,const byte * FZ_RESTRICT mp,int w,int n,int a,const fz_overprint * FZ_RESTRICT eop)1243 paint_span_with_mask_3_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
1244 {
1245 	TRACK_FN();
1246 	template_span_with_mask_3_general(dp, sp, 1, mp, w);
1247 }
1248 
1249 static void
paint_span_with_mask_3(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,const byte * FZ_RESTRICT mp,int w,int n,int a,const fz_overprint * FZ_RESTRICT eop)1250 paint_span_with_mask_3(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
1251 {
1252 	TRACK_FN();
1253 	template_span_with_mask_3_general(dp, sp, 0, mp, w);
1254 }
1255 #endif /* FZ_PLOTTERS_RGB */
1256 
1257 #if FZ_PLOTTERS_CMYK
1258 static void
paint_span_with_mask_4_a(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,const byte * FZ_RESTRICT mp,int w,int n,int a,const fz_overprint * FZ_RESTRICT eop)1259 paint_span_with_mask_4_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
1260 {
1261 	TRACK_FN();
1262 	template_span_with_mask_4_general(dp, sp, 1, mp, w);
1263 }
1264 
1265 static void
paint_span_with_mask_4(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,const byte * FZ_RESTRICT mp,int w,int n,int a,const fz_overprint * FZ_RESTRICT eop)1266 paint_span_with_mask_4(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
1267 {
1268 	TRACK_FN();
1269 	template_span_with_mask_4_general(dp, sp, 0, mp, w);
1270 }
1271 #endif /* FZ_PLOTTERS_CMYK */
1272 
1273 #if FZ_PLOTTERS_N
1274 static void
paint_span_with_mask_N_a(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,const byte * FZ_RESTRICT mp,int w,int n,int a,const fz_overprint * FZ_RESTRICT eop)1275 paint_span_with_mask_N_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
1276 {
1277 	TRACK_FN();
1278 	template_span_with_mask_N_general(dp, sp, 1, mp, n, w);
1279 }
1280 
1281 static void
paint_span_with_mask_N(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,const byte * FZ_RESTRICT mp,int w,int n,int a,const fz_overprint * FZ_RESTRICT eop)1282 paint_span_with_mask_N(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop)
1283 {
1284 	TRACK_FN();
1285 	template_span_with_mask_N_general(dp, sp, 0, mp, n, w);
1286 }
1287 #endif /* FZ_PLOTTERS_N */
1288 
1289 typedef void (fz_span_mask_painter_t)(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop);
1290 
1291 static fz_span_mask_painter_t *
fz_get_span_mask_painter(int a,int n)1292 fz_get_span_mask_painter(int a, int n)
1293 {
1294 	switch(n)
1295 	{
1296 		case 0:
1297 			/* assert(a); */
1298 			return paint_span_with_mask_0_a;
1299 		case 1:
1300 			if (a)
1301 				return paint_span_with_mask_1_a;
1302 			else
1303 				return paint_span_with_mask_1;
1304 #if FZ_PLOTTERS_RGB
1305 		case 3:
1306 			if (a)
1307 				return paint_span_with_mask_3_a;
1308 			else
1309 				return paint_span_with_mask_3;
1310 #endif /* FZ_PLOTTERS_RGB */
1311 #if FZ_PLOTTERS_CMYK
1312 		case 4:
1313 			if (a)
1314 				return paint_span_with_mask_4_a;
1315 			else
1316 				return paint_span_with_mask_4;
1317 #endif /* FZ_PLOTTERS_CMYK */
1318 		default:
1319 		{
1320 #if FZ_PLOTTERS_N
1321 			if (a)
1322 				return paint_span_with_mask_N_a;
1323 			else
1324 				return paint_span_with_mask_N;
1325 #else
1326 			return NULL;
1327 #endif /* FZ_PLOTTERS_N */
1328 		}
1329 	}
1330 }
1331 
1332 /* Blend source in constant alpha over destination */
1333 
1334 static inline void
template_span_1_with_alpha_general(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int w,int alpha)1335 template_span_1_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w, int alpha)
1336 {
1337 	if (sa)
1338 		alpha = FZ_EXPAND(alpha);
1339 	do
1340 	{
1341 		int masa = (sa ? FZ_COMBINE(sp[1], alpha) : alpha);
1342 		int t = FZ_EXPAND(255-masa);
1343 		*dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
1344 		dp++; sp++;
1345 		if (da)
1346 		{
1347 			*dp = masa + FZ_COMBINE(*dp, t);
1348 			dp++;
1349 		}
1350 		if (sa)
1351 			 sp++;
1352 	}
1353 	while (--w);
1354 }
1355 
1356 static inline void
template_span_3_with_alpha_general(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int w,int alpha)1357 template_span_3_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w, int alpha)
1358 {
1359 	if (sa)
1360 		alpha = FZ_EXPAND(alpha);
1361 	do
1362 	{
1363 		int masa = (sa ? FZ_COMBINE(sp[3], alpha) : alpha);
1364 		int t = FZ_EXPAND(255-masa);
1365 		*dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
1366 		sp++; dp++;
1367 		*dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
1368 		sp++; dp++;
1369 		*dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
1370 		sp++; dp++;
1371 		if (da)
1372 		{
1373 			*dp = masa + FZ_COMBINE(*dp, t);
1374 			dp++;
1375 		}
1376 		if (sa)
1377 			sp++;
1378 	}
1379 	while (--w);
1380 }
1381 
1382 static inline void
template_span_4_with_alpha_general(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int w,int alpha)1383 template_span_4_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w, int alpha)
1384 {
1385 	if (sa)
1386 		alpha = FZ_EXPAND(alpha);
1387 	do
1388 	{
1389 		int masa = (sa ? FZ_COMBINE(sp[4], alpha) : alpha);
1390 		int t = FZ_EXPAND(255-masa);
1391 		*dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
1392 		sp++; dp++;
1393 		*dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
1394 		sp++; dp++;
1395 		*dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
1396 		sp++; dp++;
1397 		*dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
1398 		sp++; dp++;
1399 		if (da)
1400 		{
1401 			*dp = masa + FZ_COMBINE(*dp, t);
1402 			dp++;
1403 		}
1404 		if (sa)
1405 			sp++;
1406 	}
1407 	while (--w);
1408 }
1409 
1410 #if FZ_PLOTTERS_N
1411 static inline void
template_span_N_with_alpha_general(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n1,int w,int alpha)1412 template_span_N_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w, int alpha)
1413 {
1414 	if (sa)
1415 		alpha = FZ_EXPAND(alpha);
1416 	do
1417 	{
1418 		int masa = (sa ? FZ_COMBINE(sp[n1], alpha) : alpha);
1419 		int t = FZ_EXPAND(255-masa);
1420 		int k;
1421 		for (k = 0; k < n1; k++)
1422 		{
1423 			*dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
1424 			sp++; dp++;
1425 		}
1426 		if (da)
1427 		{
1428 			*dp = masa + FZ_COMBINE(*dp, t);
1429 			dp++;
1430 		}
1431 		if (sa)
1432 			sp++;
1433 	}
1434 	while (--w);
1435 }
1436 
1437 static inline void
template_span_N_with_alpha_general_op(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n1,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1438 template_span_N_with_alpha_general_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1439 {
1440 	if (sa)
1441 		alpha = FZ_EXPAND(alpha);
1442 	do
1443 	{
1444 		int masa = (sa ? FZ_COMBINE(sp[n1], alpha) : alpha);
1445 		int t = FZ_EXPAND(255-masa);
1446 		int k;
1447 		for (k = 0; k < n1; k++)
1448 		{
1449 			if (fz_overprint_component(eop, k))
1450 				*dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t);
1451 			sp++;
1452 			dp++;
1453 		}
1454 		if (da)
1455 		{
1456 			*dp = masa + FZ_COMBINE(*dp, t);
1457 			dp++;
1458 		}
1459 		if (sa)
1460 			sp++;
1461 	}
1462 	while (--w);
1463 }
1464 #endif
1465 
1466 /* Blend source over destination */
1467 
1468 static inline void
template_span_1_general(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int w)1469 template_span_1_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w)
1470 {
1471 	do
1472 	{
1473 		int t = (sa ? FZ_EXPAND(sp[1]): 256);
1474 		if (t == 0)
1475 		{
1476 			dp += 1 + da; sp += 1 + sa;
1477 		}
1478 		else
1479 		{
1480 			t = 256 - t;
1481 			if (t == 0)
1482 			{
1483 				*dp++ = *sp++;
1484 				if (da)
1485 					*dp++ = (sa ? *sp : 255);
1486 				if (sa)
1487 					sp++;
1488 			}
1489 			else
1490 			{
1491 				*dp = *sp + FZ_COMBINE(*dp, t);
1492 				sp++;
1493 				dp++;
1494 				if (da)
1495 				{
1496 					*dp = (sa ? *sp + FZ_COMBINE(*dp, t) : 255);
1497 					dp++;
1498 				}
1499 				if (sa)
1500 					sp++;
1501 			}
1502 		}
1503 	}
1504 	while (--w);
1505 }
1506 
1507 static inline void
template_span_3_general(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int w)1508 template_span_3_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w)
1509 {
1510 	do
1511 	{
1512 		int t = (sa ? FZ_EXPAND(sp[3]) : 256);
1513 		if (t == 0)
1514 		{
1515 			dp += 3 + da; sp += 3 + sa;
1516 		}
1517 		else
1518 		{
1519 			t = 256 - t;
1520 			if (t == 0)
1521 			{
1522 				if (da && sa)
1523 					*(int32_t *)dp = *(const int32_t *)sp;
1524 				else
1525 				{
1526 					dp[0] = sp[0];
1527 					dp[1] = sp[1];
1528 					dp[2] = sp[2];
1529 					if (da)
1530 						dp[3] = 255;
1531 				}
1532 				dp += 3+da; sp += 3+sa;
1533 			}
1534 			else
1535 			{
1536 				*dp = *sp++ + FZ_COMBINE(*dp, t);
1537 				dp++;
1538 				*dp = *sp++ + FZ_COMBINE(*dp, t);
1539 				dp++;
1540 				*dp = *sp++ + FZ_COMBINE(*dp, t);
1541 				dp++;
1542 				if (da)
1543 				{
1544 					*dp = (sa ? *sp + FZ_COMBINE(*dp, t) : 255);
1545 					dp++;
1546 				}
1547 				if (sa)
1548 					sp++;
1549 			}
1550 		}
1551 	}
1552 	while (--w);
1553 }
1554 
1555 static inline void
template_span_4_general(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int w)1556 template_span_4_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w)
1557 {
1558 	do
1559 	{
1560 		int t = (sa ? FZ_EXPAND(sp[4]) : 256);
1561 		if (t == 0)
1562 		{
1563 			dp += 4+da; sp += 4+sa;
1564 		}
1565 		else
1566 		{
1567 			t = 256 - t;
1568 			if (t == 0)
1569 			{
1570 				dp[0] = sp[0];
1571 				dp[1] = sp[1];
1572 				dp[2] = sp[2];
1573 				dp[3] = sp[3];
1574 				if (da)
1575 					dp[4] = (sa ? sp[4] : 255);
1576 				dp += 4+da; sp += 4 + sa;
1577 			}
1578 			else
1579 			{
1580 				*dp = *sp++ + FZ_COMBINE(*dp, t);
1581 				dp++;
1582 				*dp = *sp++ + FZ_COMBINE(*dp, t);
1583 				dp++;
1584 				*dp = *sp++ + FZ_COMBINE(*dp, t);
1585 				dp++;
1586 				*dp = *sp++ + FZ_COMBINE(*dp, t);
1587 				dp++;
1588 				if (da)
1589 				{
1590 					*dp = (sa ? *sp + FZ_COMBINE(*dp, t) : 255);
1591 					dp++;
1592 				}
1593 				if (sa)
1594 					sp++;
1595 			}
1596 		}
1597 	}
1598 	while (--w);
1599 }
1600 
1601 #if FZ_PLOTTERS_N
1602 static inline void
template_span_N_general(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n1,int w)1603 template_span_N_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w)
1604 {
1605 	do
1606 	{
1607 		int t = (sa ? FZ_EXPAND(sp[n1]) : 256);
1608 		if (t == 0)
1609 		{
1610 			dp += n1 + da; sp += n1 + sa;
1611 		}
1612 		else
1613 		{
1614 			t = 256 - t;
1615 			if (t == 0)
1616 			{
1617 				int k;
1618 				for (k = 0; k < n1; k++)
1619 					*dp++ = *sp++;
1620 				if (da)
1621 					*dp++ = (sa ? *sp : 255);
1622 				if (sa)
1623 					sp++;
1624 			}
1625 			else
1626 			{
1627 				int k;
1628 				for (k = 0; k < n1; k++)
1629 				{
1630 					*dp = *sp + FZ_COMBINE(*dp, t);
1631 					sp++;
1632 					dp++;
1633 				}
1634 				if (da)
1635 				{
1636 					*dp = (sa ? *sp + FZ_COMBINE(*dp, t) : 255);
1637 					dp++;
1638 				}
1639 				if (sa)
1640 					sp++;
1641 			}
1642 		}
1643 	}
1644 	while (--w);
1645 }
1646 
1647 static inline void
template_span_N_general_op(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n1,int w,const fz_overprint * FZ_RESTRICT eop)1648 template_span_N_general_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w, const fz_overprint * FZ_RESTRICT eop)
1649 {
1650 	do
1651 	{
1652 		int t = (sa ? FZ_EXPAND(sp[n1]) : 256);
1653 		if (t == 0)
1654 		{
1655 			dp += n1 + da; sp += n1 + sa;
1656 		}
1657 		else
1658 		{
1659 			t = 256 - t;
1660 			if (t == 0)
1661 			{
1662 				int k;
1663 				for (k = 0; k < n1; k++)
1664 				{
1665 					if (fz_overprint_component(eop, k))
1666 						*dp = *sp;
1667 					dp++;
1668 					sp++;
1669 				}
1670 				if (da)
1671 					*dp++ = (sa ? *sp : 255);
1672 				if (sa)
1673 					sp++;
1674 			}
1675 			else
1676 			{
1677 				int k;
1678 				for (k = 0; k < n1; k++)
1679 				{
1680 					if (fz_overprint_component(eop, k))
1681 						*dp = *sp + FZ_COMBINE(*dp, t);
1682 					sp++;
1683 					dp++;
1684 				}
1685 				if (da)
1686 				{
1687 					*dp = (sa ? *sp + FZ_COMBINE(*dp, t) : 255);
1688 					dp++;
1689 				}
1690 				if (sa)
1691 					sp++;
1692 			}
1693 		}
1694 	}
1695 	while (--w);
1696 }
1697 #endif
1698 
1699 static void
paint_span_0_da_sa(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1700 paint_span_0_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1701 {
1702 	TRACK_FN();
1703 	do
1704 	{
1705 		int s = *sp++;
1706 		int t = FZ_EXPAND(255 - s);
1707 		*dp = s + FZ_COMBINE(*dp, t);
1708 		dp ++;
1709 	}
1710 	while (--w);
1711 }
1712 
1713 static void
paint_span_0_da_sa_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1714 paint_span_0_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1715 {
1716 	TRACK_FN();
1717 	alpha = FZ_EXPAND(alpha);
1718 	do
1719 	{
1720 		int masa = FZ_COMBINE(sp[0], alpha);
1721 		int t = FZ_EXPAND(255-masa);
1722 		*dp = masa + FZ_COMBINE(*dp, t);
1723 		dp++;
1724 		sp++;
1725 	}
1726 	while (--w);
1727 }
1728 
1729 static void
paint_span_1_sa(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1730 paint_span_1_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1731 {
1732 	TRACK_FN();
1733 	template_span_1_general(dp, 0, sp, 1, w);
1734 }
1735 
1736 static void
paint_span_1_sa_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1737 paint_span_1_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1738 {
1739 	TRACK_FN();
1740 	template_span_1_with_alpha_general(dp, 0, sp, 1, w, alpha);
1741 }
1742 
1743 static void
paint_span_1_da_sa(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1744 paint_span_1_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1745 {
1746 	TRACK_FN();
1747 	template_span_1_general(dp, 1, sp, 1, w);
1748 }
1749 
1750 static void
paint_span_1_da_sa_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1751 paint_span_1_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1752 {
1753 	TRACK_FN();
1754 	template_span_1_with_alpha_general(dp, 1, sp, 1, w, alpha);
1755 }
1756 
1757 #if FZ_PLOTTERS_G
1758 static void
paint_span_1_da(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1759 paint_span_1_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1760 {
1761 	TRACK_FN();
1762 	template_span_1_general(dp, 1, sp, 0, w);
1763 }
1764 
1765 static void
paint_span_1_da_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1766 paint_span_1_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1767 {
1768 	TRACK_FN();
1769 	template_span_1_with_alpha_general(dp, 1, sp, 0, w, alpha);
1770 }
1771 
1772 static void
paint_span_1(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1773 paint_span_1(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1774 {
1775 	TRACK_FN();
1776 	template_span_1_general(dp, 0, sp, 0, w);
1777 }
1778 
1779 static void
paint_span_1_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1780 paint_span_1_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1781 {
1782 	TRACK_FN();
1783 	template_span_1_with_alpha_general(dp, 0, sp, 0, w, alpha);
1784 }
1785 #endif /* FZ_PLOTTERS_G */
1786 
1787 #if FZ_PLOTTERS_RGB
1788 static void
paint_span_3_da_sa(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1789 paint_span_3_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1790 {
1791 	TRACK_FN();
1792 	template_span_3_general(dp, 1, sp, 1, w);
1793 }
1794 
1795 static void
paint_span_3_da_sa_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1796 paint_span_3_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1797 {
1798 	TRACK_FN();
1799 	template_span_3_with_alpha_general(dp, 1, sp, 1, w, alpha);
1800 }
1801 
1802 static void
paint_span_3_da(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1803 paint_span_3_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1804 {
1805 	TRACK_FN();
1806 	template_span_3_general(dp, 1, sp, 0, w);
1807 }
1808 
1809 static void
paint_span_3_da_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1810 paint_span_3_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1811 {
1812 	TRACK_FN();
1813 	template_span_3_with_alpha_general(dp, 1, sp, 0, w, alpha);
1814 }
1815 
1816 static void
paint_span_3_sa(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1817 paint_span_3_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1818 {
1819 	TRACK_FN();
1820 	template_span_3_general(dp, 0, sp, 1, w);
1821 }
1822 
1823 static void
paint_span_3_sa_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1824 paint_span_3_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1825 {
1826 	TRACK_FN();
1827 	template_span_3_with_alpha_general(dp, 0, sp, 1, w, alpha);
1828 }
1829 
1830 static void
paint_span_3(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1831 paint_span_3(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1832 {
1833 	TRACK_FN();
1834 	template_span_3_general(dp, 0, sp, 0, w);
1835 }
1836 
1837 static void
paint_span_3_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1838 paint_span_3_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1839 {
1840 	TRACK_FN();
1841 	template_span_3_with_alpha_general(dp, 0, sp, 0, w, alpha);
1842 }
1843 #endif /* FZ_PLOTTERS_RGB */
1844 
1845 #if FZ_PLOTTERS_CMYK
1846 static void
paint_span_4_da_sa(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1847 paint_span_4_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1848 {
1849 	TRACK_FN();
1850 	template_span_4_general(dp, 1, sp, 1, w);
1851 }
1852 
1853 static void
paint_span_4_da_sa_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1854 paint_span_4_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1855 {
1856 	TRACK_FN();
1857 	template_span_4_with_alpha_general(dp, 1, sp, 1, w, alpha);
1858 }
1859 
1860 static void
paint_span_4_da(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1861 paint_span_4_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1862 {
1863 	TRACK_FN();
1864 	template_span_4_general(dp, 1, sp, 0, w);
1865 }
1866 
1867 static void
paint_span_4_da_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1868 paint_span_4_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1869 {
1870 	TRACK_FN();
1871 	template_span_4_with_alpha_general(dp, 1, sp, 0, w, alpha);
1872 }
1873 
1874 static void
paint_span_4_sa(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1875 paint_span_4_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1876 {
1877 	TRACK_FN();
1878 	template_span_4_general(dp, 0, sp, 1, w);
1879 }
1880 
1881 static void
paint_span_4_sa_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1882 paint_span_4_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1883 {
1884 	TRACK_FN();
1885 	template_span_4_with_alpha_general(dp, 0, sp, 1, w, alpha);
1886 }
1887 
1888 static void
paint_span_4(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1889 paint_span_4(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1890 {
1891 	TRACK_FN();
1892 	template_span_4_general(dp, 0, sp, 0, w);
1893 }
1894 
1895 static void
paint_span_4_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1896 paint_span_4_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1897 {
1898 	TRACK_FN();
1899 	template_span_4_with_alpha_general(dp, 0, sp, 0, w, alpha);
1900 }
1901 #endif /* FZ_PLOTTERS_CMYK */
1902 
1903 #if FZ_PLOTTERS_N
1904 static void
paint_span_N_da_sa(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1905 paint_span_N_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1906 {
1907 	TRACK_FN();
1908 	template_span_N_general(dp, 1, sp, 1, n, w);
1909 }
1910 
1911 static void
paint_span_N_da_sa_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1912 paint_span_N_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1913 {
1914 	TRACK_FN();
1915 	template_span_N_with_alpha_general(dp, 1, sp, 1, n, w, alpha);
1916 }
1917 
1918 static void
paint_span_N_da(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1919 paint_span_N_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1920 {
1921 	TRACK_FN();
1922 	template_span_N_general(dp, 1, sp, 0, n, w);
1923 }
1924 
1925 static void
paint_span_N_da_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1926 paint_span_N_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1927 {
1928 	TRACK_FN();
1929 	template_span_N_with_alpha_general(dp, 1, sp, 0, n, w, alpha);
1930 }
1931 
1932 static void
paint_span_N_sa(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1933 paint_span_N_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1934 {
1935 	TRACK_FN();
1936 	template_span_N_general(dp, 0, sp, 1, n, w);
1937 }
1938 
1939 static void
paint_span_N_sa_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1940 paint_span_N_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1941 {
1942 	TRACK_FN();
1943 	template_span_N_with_alpha_general(dp, 0, sp, 1, n, w, alpha);
1944 }
1945 
1946 static void
paint_span_N(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1947 paint_span_N(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1948 {
1949 	TRACK_FN();
1950 	template_span_N_general(dp, 0, sp, 0, n, w);
1951 }
1952 
1953 static void
paint_span_N_alpha(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1954 paint_span_N_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1955 {
1956 	TRACK_FN();
1957 	template_span_N_with_alpha_general(dp, 0, sp, 0, n, w, alpha);
1958 }
1959 #endif /* FZ_PLOTTERS_N */
1960 
1961 #if FZ_ENABLE_SPOT_RENDERING
1962 static void
paint_span_N_general_op(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1963 paint_span_N_general_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1964 {
1965 	TRACK_FN();
1966 	template_span_N_general_op(dp, da, sp, sa, n, w, eop);
1967 }
1968 
1969 static void
paint_span_N_general_alpha_op(byte * FZ_RESTRICT dp,int da,const byte * FZ_RESTRICT sp,int sa,int n,int w,int alpha,const fz_overprint * FZ_RESTRICT eop)1970 paint_span_N_general_alpha_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop)
1971 {
1972 	TRACK_FN();
1973 	template_span_N_with_alpha_general_op(dp, da, sp, sa, n, w, alpha, eop);
1974 }
1975 #endif /* FZ_ENABLE_SPOT_RENDERING */
1976 
1977 fz_span_painter_t *
fz_get_span_painter(int da,int sa,int n,int alpha,const fz_overprint * FZ_RESTRICT eop)1978 fz_get_span_painter(int da, int sa, int n, int alpha, const fz_overprint * FZ_RESTRICT eop)
1979 {
1980 #if FZ_ENABLE_SPOT_RENDERING
1981 	if (fz_overprint_required(eop))
1982 	{
1983 		if (alpha == 255)
1984 			return paint_span_N_general_op;
1985 		else if (alpha > 0)
1986 			return paint_span_N_general_alpha_op;
1987 		else
1988 			return NULL;
1989 	}
1990 #endif /* FZ_ENABLE_SPOT_RENDERING */
1991 	switch (n)
1992 	{
1993 	case 0:
1994 		if (alpha == 255)
1995 			return paint_span_0_da_sa;
1996 		else if (alpha > 0)
1997 			return paint_span_0_da_sa_alpha;
1998 		break;
1999 	case 1:
2000 		if (sa)
2001 			if (da)
2002 			{
2003 				if (alpha == 255)
2004 					return paint_span_1_da_sa;
2005 				else if (alpha > 0)
2006 					return paint_span_1_da_sa_alpha;
2007 			}
2008 			else
2009 			{
2010 				if (alpha == 255)
2011 					return paint_span_1_sa;
2012 				else if (alpha > 0)
2013 					return paint_span_1_sa_alpha;
2014 			}
2015 		else
2016 #if FZ_PLOTTERS_G
2017 			if (da)
2018 			{
2019 				if (alpha == 255)
2020 					return paint_span_1_da;
2021 				else if (alpha > 0)
2022 					return paint_span_1_da_alpha;
2023 			}
2024 			else
2025 			{
2026 				if (alpha == 255)
2027 					return paint_span_1;
2028 				else if (alpha > 0)
2029 					return paint_span_1_alpha;
2030 			}
2031 #else
2032 			goto fallback;
2033 #endif /* FZ_PLOTTERS_G */
2034 		break;
2035 #if FZ_PLOTTERS_RGB
2036 	case 3:
2037 		if (da)
2038 			if (sa)
2039 			{
2040 				if (alpha == 255)
2041 					return paint_span_3_da_sa;
2042 				else if (alpha > 0)
2043 					return paint_span_3_da_sa_alpha;
2044 			}
2045 			else
2046 			{
2047 				if (alpha == 255)
2048 					return paint_span_3_da;
2049 				else if (alpha > 0)
2050 					return paint_span_3_da_alpha;
2051 			}
2052 		else
2053 			if (sa)
2054 			{
2055 				if (alpha == 255)
2056 					return paint_span_3_sa;
2057 				else if (alpha > 0)
2058 					return paint_span_3_sa_alpha;
2059 			}
2060 			else
2061 			{
2062 				if (alpha == 255)
2063 					return paint_span_3;
2064 				else if (alpha > 0)
2065 					return paint_span_3_alpha;
2066 			}
2067 		break;
2068 #endif /* FZ_PLOTTERS_RGB */
2069 #if FZ_PLOTTERS_CMYK
2070 	case 4:
2071 		if (da)
2072 			if (sa)
2073 			{
2074 				if (alpha == 255)
2075 					return paint_span_4_da_sa;
2076 				else if (alpha > 0)
2077 					return paint_span_4_da_sa_alpha;
2078 			}
2079 			else
2080 			{
2081 				if (alpha == 255)
2082 					return paint_span_4_da;
2083 				else if (alpha > 0)
2084 					return paint_span_4_da_alpha;
2085 			}
2086 		else
2087 			if (sa)
2088 			{
2089 				if (alpha == 255)
2090 					return paint_span_4_sa;
2091 				else if (alpha > 0)
2092 					return paint_span_4_sa_alpha;
2093 			}
2094 			else
2095 			{
2096 				if (alpha == 255)
2097 					return paint_span_4;
2098 				else if (alpha > 0)
2099 					return paint_span_4_alpha;
2100 			}
2101 		break;
2102 #endif /* FZ_PLOTTERS_CMYK */
2103 	default:
2104 	{
2105 #if !FZ_PLOTTERS_G
2106 fallback:{}
2107 #endif /* FZ_PLOTTERS_G */
2108 #if FZ_PLOTTERS_N
2109 		if (da)
2110 			if (sa)
2111 			{
2112 				if (alpha == 255)
2113 					return paint_span_N_da_sa;
2114 				else if (alpha > 0)
2115 					return paint_span_N_da_sa_alpha;
2116 			}
2117 			else
2118 			{
2119 				if (alpha == 255)
2120 					return paint_span_N_da;
2121 				else if (alpha > 0)
2122 					return paint_span_N_da_alpha;
2123 			}
2124 		else
2125 			if (sa)
2126 			{
2127 				if (alpha == 255)
2128 					return paint_span_N_sa;
2129 				else if (alpha > 0)
2130 					return paint_span_N_sa_alpha;
2131 			}
2132 			else
2133 			{
2134 				if (alpha == 255)
2135 					return paint_span_N;
2136 				else if (alpha > 0)
2137 					return paint_span_N_alpha;
2138 			}
2139 #endif /* FZ_PLOTTERS_N */
2140 		break;
2141 	}
2142 	}
2143 	return NULL;
2144 }
2145 
2146 /*
2147  * Pixmap blending functions
2148  */
2149 
2150 void
fz_paint_pixmap_with_bbox(fz_pixmap * FZ_RESTRICT dst,const fz_pixmap * FZ_RESTRICT src,int alpha,fz_irect bbox)2151 fz_paint_pixmap_with_bbox(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, int alpha, fz_irect bbox)
2152 {
2153 	const unsigned char *sp;
2154 	unsigned char *dp;
2155 	int x, y, w, h, n, da, sa;
2156 	fz_span_painter_t *fn;
2157 
2158 	assert(dst->n - dst->alpha == src->n - src->alpha);
2159 
2160 	if (alpha == 0)
2161 		return;
2162 
2163 	bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(dst));
2164 	bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src));
2165 
2166 	x = bbox.x0;
2167 	y = bbox.y0;
2168 	w = bbox.x1 - bbox.x0;
2169 	h = bbox.y1 - bbox.y0;
2170 	if (w == 0 || h == 0)
2171 		return;
2172 
2173 	n = src->n;
2174 	sp = src->samples + (unsigned int)((y - src->y) * src->stride + (x - src->x) * src->n);
2175 	sa = src->alpha;
2176 	dp = dst->samples + (unsigned int)((y - dst->y) * dst->stride + (x - dst->x) * dst->n);
2177 	da = dst->alpha;
2178 
2179 	n -= sa;
2180 	fn = fz_get_span_painter(da, sa, n, alpha, 0);
2181 	assert(fn);
2182 	if (fn == NULL)
2183 		return;
2184 
2185 	while (h--)
2186 	{
2187 		(*fn)(dp, da, sp, sa, n, w, alpha, 0);
2188 		sp += src->stride;
2189 		dp += dst->stride;
2190 	}
2191 }
2192 
2193 void
fz_paint_pixmap(fz_pixmap * FZ_RESTRICT dst,const fz_pixmap * FZ_RESTRICT src,int alpha)2194 fz_paint_pixmap(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, int alpha)
2195 {
2196 	const unsigned char *sp;
2197 	unsigned char *dp;
2198 	fz_irect bbox;
2199 	int x, y, w, h, n, da, sa;
2200 	fz_span_painter_t *fn;
2201 
2202 	if (alpha == 0)
2203 		return;
2204 
2205 	if (dst->n - dst->alpha != src->n - src->alpha)
2206 	{
2207 		// fprintf(stderr, "fz_paint_pixmap - FIXME\n");
2208 		return;
2209 	}
2210 	assert(dst->n - dst->alpha == src->n - src->alpha);
2211 
2212 	bbox = fz_intersect_irect(fz_pixmap_bbox_no_ctx(src), fz_pixmap_bbox_no_ctx(dst));
2213 	x = bbox.x0;
2214 	y = bbox.y0;
2215 	w = bbox.x1 - bbox.x0;
2216 	h = bbox.y1 - bbox.y0;
2217 	if (w == 0 || h == 0)
2218 		return;
2219 
2220 	n = src->n;
2221 	sp = src->samples + (unsigned int)((y - src->y) * src->stride + (x - src->x) * src->n);
2222 	sa = src->alpha;
2223 	dp = dst->samples + (unsigned int)((y - dst->y) * dst->stride + (x - dst->x) * dst->n);
2224 	da = dst->alpha;
2225 
2226 	n -= sa;
2227 	fn = fz_get_span_painter(da, sa, n, alpha, 0);
2228 	assert(fn);
2229 	if (fn == NULL)
2230 		return;
2231 
2232 	while (h--)
2233 	{
2234 		(*fn)(dp, da, sp, sa, n, w, alpha, 0);
2235 		sp += src->stride;
2236 		dp += dst->stride;
2237 	}
2238 }
2239 
2240 static inline void
paint_span_alpha_solid(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,int n,int w)2241 paint_span_alpha_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int n, int w)
2242 {
2243 	TRACK_FN();
2244 	sp += n-1;
2245 	do
2246 	{
2247 		int s = *sp;
2248 		int t = FZ_EXPAND(255 - s);
2249 		sp += n;
2250 		*dp = s + FZ_COMBINE(*dp, t);
2251 		dp ++;
2252 	}
2253 	while (--w);
2254 }
2255 
2256 static inline void
paint_span_alpha_not_solid(byte * FZ_RESTRICT dp,const byte * FZ_RESTRICT sp,int n,int w,int alpha)2257 paint_span_alpha_not_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int n, int w, int alpha)
2258 {
2259 	TRACK_FN();
2260 	sp += n-1;
2261 	alpha = FZ_EXPAND(alpha);
2262 	do
2263 	{
2264 		int masa = FZ_COMBINE(sp[0], alpha);
2265 		sp += n;
2266 		*dp = FZ_BLEND(*sp, *dp, masa);
2267 		dp++;
2268 	}
2269 	while (--w);
2270 }
2271 
2272 void
fz_paint_pixmap_alpha(fz_pixmap * FZ_RESTRICT dst,const fz_pixmap * FZ_RESTRICT src,int alpha)2273 fz_paint_pixmap_alpha(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, int alpha)
2274 {
2275 	const unsigned char *sp;
2276 	unsigned char *dp;
2277 	fz_irect bbox;
2278 	int x, y, w, h, n;
2279 
2280 	if (alpha == 0)
2281 		return;
2282 
2283 	assert(dst->n == 1 && dst->alpha == 1 && src->n >= 1 && src->alpha == 1);
2284 
2285 	bbox = fz_intersect_irect(fz_pixmap_bbox_no_ctx(src), fz_pixmap_bbox_no_ctx(dst));
2286 	x = bbox.x0;
2287 	y = bbox.y0;
2288 	w = bbox.x1 - bbox.x0;
2289 	h = bbox.y1 - bbox.y0;
2290 	if (w == 0 || h == 0)
2291 		return;
2292 
2293 	n = src->n;
2294 	sp = src->samples + (unsigned int)((y - src->y) * src->stride + (x - src->x) * src->n);
2295 	dp = dst->samples + (unsigned int)((y - dst->y) * dst->stride + (x - dst->x) * dst->n);
2296 
2297 	if (alpha == 255)
2298 	{
2299 		while (h--)
2300 		{
2301 			paint_span_alpha_solid(dp, sp, n, w);
2302 			sp += src->stride;
2303 			dp += dst->stride;
2304 		}
2305 	}
2306 	else
2307 	{
2308 		while (h--)
2309 		{
2310 			paint_span_alpha_not_solid(dp, sp, n, w, alpha);
2311 			sp += src->stride;
2312 			dp += dst->stride;
2313 		}
2314 	}
2315 }
2316 
2317 void
fz_paint_pixmap_with_overprint(fz_pixmap * FZ_RESTRICT dst,const fz_pixmap * FZ_RESTRICT src,const fz_overprint * FZ_RESTRICT eop)2318 fz_paint_pixmap_with_overprint(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, const fz_overprint * FZ_RESTRICT eop)
2319 {
2320 	const unsigned char *sp;
2321 	unsigned char *dp;
2322 	fz_irect bbox;
2323 	int x, y, w, h, n, da, sa;
2324 	fz_span_painter_t *fn;
2325 
2326 	if (dst->n - dst->alpha != src->n - src->alpha)
2327 	{
2328 		// fprintf(stderr, "fz_paint_pixmap_with_overprint - FIXME\n");
2329 		return;
2330 	}
2331 	assert(dst->n - dst->alpha == src->n - src->alpha);
2332 
2333 	bbox = fz_intersect_irect(fz_pixmap_bbox_no_ctx(src), fz_pixmap_bbox_no_ctx(dst));
2334 	x = bbox.x0;
2335 	y = bbox.y0;
2336 	w = bbox.x1 - bbox.x0;
2337 	h = bbox.y1 - bbox.y0;
2338 	if (w == 0 || h == 0)
2339 		return;
2340 
2341 	n = src->n;
2342 	sp = src->samples + (unsigned int)((y - src->y) * src->stride + (x - src->x) * src->n);
2343 	sa = src->alpha;
2344 	dp = dst->samples + (unsigned int)((y - dst->y) * dst->stride + (x - dst->x) * dst->n);
2345 	da = dst->alpha;
2346 
2347 	n -= sa;
2348 	fn = fz_get_span_painter(da, sa, n, 255, eop);
2349 	assert(fn);
2350 	if (fn == NULL)
2351 		return;
2352 
2353 	while (h--)
2354 	{
2355 		(*fn)(dp, da, sp, sa, n, w, 255, eop);
2356 		sp += src->stride;
2357 		dp += dst->stride;
2358 	}
2359 }
2360 
2361 void
fz_paint_pixmap_with_mask(fz_pixmap * FZ_RESTRICT dst,const fz_pixmap * FZ_RESTRICT src,const fz_pixmap * FZ_RESTRICT msk)2362 fz_paint_pixmap_with_mask(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, const fz_pixmap * FZ_RESTRICT msk)
2363 {
2364 	const unsigned char *sp, *mp;
2365 	unsigned char *dp;
2366 	fz_irect bbox;
2367 	int x, y, w, h, n, sa, da;
2368 	fz_span_mask_painter_t *fn;
2369 
2370 	assert(dst->n == src->n);
2371 	assert(msk->n == 1);
2372 
2373 	bbox = fz_pixmap_bbox_no_ctx(dst);
2374 	bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src));
2375 	bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(msk));
2376 
2377 	x = bbox.x0;
2378 	y = bbox.y0;
2379 	w = bbox.x1 - bbox.x0;
2380 	h = bbox.y1 - bbox.y0;
2381 	if (w == 0 || h == 0)
2382 		return;
2383 
2384 	n = src->n;
2385 	sp = src->samples + (unsigned int)((y - src->y) * src->stride + (x - src->x) * src->n);
2386 	sa = src->alpha;
2387 	mp = msk->samples + (unsigned int)((y - msk->y) * msk->stride + (x - msk->x) * msk->n);
2388 	dp = dst->samples + (unsigned int)((y - dst->y) * dst->stride + (x - dst->x) * dst->n);
2389 	da = dst->alpha;
2390 
2391 	/* sa == da, or something has gone very wrong! */
2392 	assert(sa == da);
2393 
2394 	n -= sa;
2395 	fn = fz_get_span_mask_painter(da, n);
2396 	if (fn == NULL)
2397 		return;
2398 
2399 	while (h--)
2400 	{
2401 		(*fn)(dp, sp, mp, w, n, sa, NULL);
2402 		sp += src->stride;
2403 		dp += dst->stride;
2404 		mp += msk->stride;
2405 	}
2406 }
2407 
2408 static inline void
fz_paint_glyph_mask(int span,unsigned char * dp,int da,const fz_glyph * glyph,int w,int h,int skip_x,int skip_y)2409 fz_paint_glyph_mask(int span, unsigned char *dp, int da, const fz_glyph *glyph, int w, int h, int skip_x, int skip_y)
2410 {
2411 	while (h--)
2412 	{
2413 		int skip_xx, ww, len, extend;
2414 		const unsigned char *runp;
2415 		unsigned char *ddp = dp;
2416 		int offset = ((const int *)(glyph->data))[skip_y++];
2417 		if (offset >= 0)
2418 		{
2419 			int eol = 0;
2420 			runp = &glyph->data[offset];
2421 			extend = 0;
2422 			ww = w;
2423 			skip_xx = skip_x;
2424 			while (skip_xx)
2425 			{
2426 				int v = *runp++;
2427 				switch (v & 3)
2428 				{
2429 				case 0: /* Extend */
2430 					extend = v>>2;
2431 					len = 0;
2432 					break;
2433 				case 1: /* Transparent */
2434 					len = (v>>2) + 1 + (extend<<6);
2435 					extend = 0;
2436 					if (len > skip_xx)
2437 					{
2438 						len -= skip_xx;
2439 						goto transparent_run;
2440 					}
2441 					break;
2442 				case 2: /* Solid */
2443 					eol = v & 4;
2444 					len = (v>>3) + 1 + (extend<<5);
2445 					extend = 0;
2446 					if (len > skip_xx)
2447 					{
2448 						len -= skip_xx;
2449 						goto solid_run;
2450 					}
2451 					break;
2452 				default: /* Intermediate */
2453 					eol = v & 4;
2454 					len = (v>>3) + 1 + (extend<<5);
2455 					extend = 0;
2456 					if (len > skip_xx)
2457 					{
2458 						runp += skip_xx;
2459 						len -= skip_xx;
2460 						goto intermediate_run;
2461 					}
2462 					runp += len;
2463 					break;
2464 				}
2465 				if (eol)
2466 				{
2467 					ww = 0;
2468 					break;
2469 				}
2470 				skip_xx -= len;
2471 			}
2472 			while (ww > 0)
2473 			{
2474 				int v = *runp++;
2475 				switch(v & 3)
2476 				{
2477 				case 0: /* Extend */
2478 					extend = v>>2;
2479 					break;
2480 				case 1: /* Transparent */
2481 					len = (v>>2) + 1 + (extend<<6);
2482 					extend = 0;
2483 transparent_run:
2484 					if (len > ww)
2485 						len = ww;
2486 					ww -= len;
2487 					ddp += len;
2488 					break;
2489 				case 2: /* Solid */
2490 					eol = v & 4;
2491 					len = (v>>3) + 1 + (extend<<5);
2492 					extend = 0;
2493 solid_run:
2494 					if (len > ww)
2495 						len = ww;
2496 					ww -= len;
2497 					do
2498 					{
2499 						*ddp++ = 0xFF;
2500 					}
2501 					while (--len);
2502 					break;
2503 				default: /* Intermediate */
2504 					eol = v & 4;
2505 					len = (v>>3) + 1 + (extend<<5);
2506 					extend = 0;
2507 intermediate_run:
2508 					if (len > ww)
2509 						len = ww;
2510 					ww -= len;
2511 					do
2512 					{
2513 						int v = *ddp;
2514 						int a = *runp++;
2515 						if (v == 0)
2516 						{
2517 							*ddp++ = a;
2518 						}
2519 						else
2520 						{
2521 							a = FZ_EXPAND(a);
2522 							*ddp = FZ_BLEND(0xFF, v, a);
2523 							ddp++;
2524 						}
2525 					}
2526 					while (--len);
2527 					break;
2528 				}
2529 				if (eol)
2530 					break;
2531 			}
2532 		}
2533 		dp += span;
2534 	}
2535 }
2536 
2537 #define N 1
2538 #include "paint-glyph.h"
2539 
2540 #define ALPHA
2541 #define N 1
2542 #include "paint-glyph.h"
2543 
2544 #if FZ_PLOTTERS_G
2545 #define DA
2546 #define N 1
2547 #include "paint-glyph.h"
2548 
2549 #define DA
2550 #define ALPHA
2551 #define N 1
2552 #include "paint-glyph.h"
2553 #endif /* FZ_PLOTTERS_G */
2554 
2555 #if FZ_PLOTTERS_RGB
2556 #define DA
2557 #define N 3
2558 #include "paint-glyph.h"
2559 
2560 #define DA
2561 #define ALPHA
2562 #define N 3
2563 #include "paint-glyph.h"
2564 
2565 #define N 3
2566 #include "paint-glyph.h"
2567 
2568 #define ALPHA
2569 #define N 3
2570 #include "paint-glyph.h"
2571 #endif /* FZ_PLOTTERS_RGB */
2572 
2573 #if FZ_PLOTTERS_CMYK
2574 #define DA
2575 #define N 4
2576 #include "paint-glyph.h"
2577 
2578 #define DA
2579 #define ALPHA
2580 #define N 4
2581 #include "paint-glyph.h"
2582 
2583 #define ALPHA
2584 #define N 4
2585 #include "paint-glyph.h"
2586 
2587 #define N 4
2588 #include "paint-glyph.h"
2589 #endif /* FZ_PLOTTERS_CMYK */
2590 
2591 #if FZ_PLOTTERS_N
2592 #define ALPHA
2593 #include "paint-glyph.h"
2594 
2595 #define DA
2596 #include "paint-glyph.h"
2597 
2598 #define DA
2599 #define ALPHA
2600 #include "paint-glyph.h"
2601 
2602 #include "paint-glyph.h"
2603 #endif /* FZ_PLOTTERS_N */
2604 
2605 #if FZ_ENABLE_SPOT_RENDERING
2606 #define ALPHA
2607 #define EOP
2608 #include "paint-glyph.h"
2609 
2610 #define DA
2611 #define EOP
2612 #include "paint-glyph.h"
2613 
2614 #define DA
2615 #define ALPHA
2616 #define EOP
2617 #include "paint-glyph.h"
2618 
2619 #define EOP
2620 #include "paint-glyph.h"
2621 #endif /* FZ_ENABLE_SPOT_RENDERING */
2622 
2623 static inline void
fz_paint_glyph_alpha(const unsigned char * FZ_RESTRICT colorbv,int n,int span,unsigned char * FZ_RESTRICT dp,int da,const fz_glyph * glyph,int w,int h,int skip_x,int skip_y,const fz_overprint * FZ_RESTRICT eop)2624 fz_paint_glyph_alpha(const unsigned char * FZ_RESTRICT colorbv, int n, int span, unsigned char * FZ_RESTRICT dp, int da, const fz_glyph *glyph, int w, int h, int skip_x, int skip_y, const fz_overprint * FZ_RESTRICT eop)
2625 {
2626 #if FZ_ENABLE_SPOT_RENDERING
2627 	if (fz_overprint_required(eop))
2628 	{
2629 		if (da)
2630 			fz_paint_glyph_alpha_N_da_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop);
2631 		else
2632 			fz_paint_glyph_alpha_N_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop);
2633 		return;
2634 	}
2635 #endif /* FZ_ENABLE_SPOT_RENDERING */
2636 	switch (n)
2637 	{
2638 	case 1:
2639 		if (da)
2640 #if FZ_PLOTTERS_G
2641 			fz_paint_glyph_alpha_1_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2642 #else
2643 			goto fallback;
2644 #endif /* FZ_PLOTTERS_G */
2645 		else
2646 			fz_paint_glyph_alpha_1(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2647 		break;
2648 #if FZ_PLOTTERS_RGB
2649 	case 3:
2650 		if (da)
2651 			fz_paint_glyph_alpha_3_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2652 		else
2653 			fz_paint_glyph_alpha_3(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2654 		break;
2655 #endif /* FZ_PLOTTERS_RGB */
2656 #if FZ_PLOTTERS_CMYK
2657 	case 4:
2658 		if (da)
2659 			fz_paint_glyph_alpha_4_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2660 		else
2661 			fz_paint_glyph_alpha_4(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2662 		break;
2663 #endif /* FZ_PLOTTERS_CMYK */
2664 	default:
2665 	{
2666 #if !FZ_PLOTTERS_G
2667 fallback:{}
2668 #endif /* !FZ_PLOTTERS_G */
2669 #if FZ_PLOTTERS_N
2670 		if (da)
2671 			fz_paint_glyph_alpha_N_da(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
2672 		else
2673 			fz_paint_glyph_alpha_N(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
2674 #endif /* FZ_PLOTTERS_N */
2675 		break;
2676 	}
2677 	}
2678 }
2679 
2680 static inline void
fz_paint_glyph_solid(const unsigned char * FZ_RESTRICT colorbv,int n,int span,unsigned char * FZ_RESTRICT dp,int da,const fz_glyph * FZ_RESTRICT glyph,int w,int h,int skip_x,int skip_y,const fz_overprint * FZ_RESTRICT eop)2681 fz_paint_glyph_solid(const unsigned char * FZ_RESTRICT colorbv, int n, int span, unsigned char * FZ_RESTRICT dp, int da, const fz_glyph * FZ_RESTRICT glyph, int w, int h, int skip_x, int skip_y, const fz_overprint * FZ_RESTRICT eop)
2682 {
2683 #if FZ_ENABLE_SPOT_RENDERING
2684 	if (fz_overprint_required(eop))
2685 	{
2686 		if (da)
2687 			fz_paint_glyph_solid_N_da_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop);
2688 		else
2689 			fz_paint_glyph_solid_N_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop);
2690 		return;
2691 	}
2692 #endif /* FZ_ENABLE_SPOT_RENDERING */
2693 	switch (n)
2694 	{
2695 	case 1:
2696 		if (da)
2697 #if FZ_PLOTTERS_G
2698 			fz_paint_glyph_solid_1_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2699 #else
2700 			goto fallback;
2701 #endif /* FZ_PLOTTERS_G */
2702 		else
2703 			fz_paint_glyph_solid_1(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2704 		break;
2705 #if FZ_PLOTTERS_RGB
2706 	case 3:
2707 		if (da)
2708 			fz_paint_glyph_solid_3_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2709 		else
2710 			fz_paint_glyph_solid_3(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2711 		break;
2712 #endif /* FZ_PLOTTERS_RGB */
2713 #if FZ_PLOTTERS_CMYK
2714 	case 4:
2715 		if (da)
2716 			fz_paint_glyph_solid_4_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2717 		else
2718 			fz_paint_glyph_solid_4(colorbv, span, dp, glyph, w, h, skip_x, skip_y);
2719 		break;
2720 #endif /* FZ_PLOTTERS_CMYK */
2721 	default:
2722 	{
2723 #if !FZ_PLOTTERS_G
2724 fallback:{}
2725 #endif /* FZ_PLOTTERS_G */
2726 #if FZ_PLOTTERS_N
2727 		if (da)
2728 			fz_paint_glyph_solid_N_da(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
2729 		else
2730 			fz_paint_glyph_solid_N(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y);
2731 		break;
2732 #endif /* FZ_PLOTTERS_N */
2733 	}
2734 	}
2735 }
2736 
2737 void
fz_paint_glyph(const unsigned char * FZ_RESTRICT colorbv,fz_pixmap * FZ_RESTRICT dst,unsigned char * FZ_RESTRICT dp,const fz_glyph * FZ_RESTRICT glyph,int w,int h,int skip_x,int skip_y,const fz_overprint * FZ_RESTRICT eop)2738 fz_paint_glyph(const unsigned char * FZ_RESTRICT colorbv, fz_pixmap * FZ_RESTRICT dst, unsigned char * FZ_RESTRICT dp, const fz_glyph * FZ_RESTRICT glyph, int w, int h, int skip_x, int skip_y, const fz_overprint * FZ_RESTRICT eop)
2739 {
2740 	int n = dst->n - dst->alpha;
2741 	if (dst->colorspace)
2742 	{
2743 		assert(n > 0);
2744 		if (colorbv[n] == 255)
2745 			fz_paint_glyph_solid(colorbv, n, dst->stride, dp, dst->alpha, glyph, w, h, skip_x, skip_y, eop);
2746 		else if (colorbv[n] != 0)
2747 			fz_paint_glyph_alpha(colorbv, n, dst->stride, dp, dst->alpha, glyph, w, h, skip_x, skip_y, eop);
2748 	}
2749 	else
2750 	{
2751 		assert(dst->alpha && dst->n == 1 && dst->colorspace == NULL && !fz_overprint_required(eop));
2752 		fz_paint_glyph_mask(dst->stride, dp, dst->alpha, glyph, w, h, skip_x, skip_y);
2753 	}
2754 }
2755