1/*
2 This file is #included by draw-paint.c multiple times to
3 produce optimised plotters.
4*/
5
6#ifdef ALPHA
7#define NAME alpha
8#else
9#define NAME solid
10#endif
11
12#ifdef DA
13#define NAME2 _da
14#else
15#define NAME2
16#endif
17
18#ifdef EOP
19#define NAME3 _op
20#else
21#define NAME3
22#endif
23
24#define FUNCTION_NAMER(NAME,N,NAME2,NAME3) fz_paint_glyph_##NAME##_##N##NAME2##NAME3
25#define FUNCTION_NAME(NAME,N,NAME2,NAME3) FUNCTION_NAMER(NAME,N,NAME2,NAME3)
26
27#ifdef EOP
28#define IF_OVERPRINT_COMPONENT(k) if (fz_overprint_component(eop, k))
29#else
30#define IF_OVERPRINT_COMPONENT(k) if (1)
31#endif
32
33static inline void
34FUNCTION_NAME(NAME,N,NAME2,NAME3)(const unsigned char * FZ_RESTRICT colorbv,
35#ifndef N
36 const int n1,
37#endif
38 int span, unsigned char * FZ_RESTRICT dp, const fz_glyph *glyph, int w, int h, int skip_x, int skip_y
39#ifdef EOP
40 , const fz_overprint *eop
41#endif
42 )
43{
44#ifdef N
45 const int n1 = N;
46#endif
47#ifdef DA
48 const int n = n1 + 1;
49#else
50 const int n = n1;
51#endif
52#ifdef ALPHA
53 int sa = FZ_EXPAND(colorbv[n1]);
54#else
55#if defined(N) && N == 1 && defined(DA)
56 const uint16_t color = *(const uint16_t *)colorbv;
57#elif defined(N) && N == 3 && defined(DA)
58 const uint32_t color = *(const uint32_t *)colorbv;
59#elif defined(N) && N == 4 && !defined(DA)
60 const uint32_t color = *(const uint32_t *)colorbv;
61#endif
62#endif
63 TRACK_FN();
64 while (h--)
65 {
66 int skip_xx, ww, len, extend;
67 const unsigned char *runp;
68 unsigned char *ddp = dp;
69 int offset = ((int *)(glyph->data))[skip_y++];
70 if (offset >= 0)
71 {
72 int eol = 0;
73 runp = &glyph->data[offset];
74 extend = 0;
75 ww = w;
76 skip_xx = skip_x;
77 while (skip_xx)
78 {
79 int v = *runp++;
80 switch (v & 3)
81 {
82 case 0: /* Extend */
83 extend = v>>2;
84 len = 0;
85 break;
86 case 1: /* Transparent */
87 len = (v>>2) + 1 + (extend<<6);
88 extend = 0;
89 if (len > skip_xx)
90 {
91 len -= skip_xx;
92 goto transparent_run;
93 }
94 break;
95 case 2: /* Solid */
96 eol = v & 4;
97 len = (v>>3) + 1 + (extend<<5);
98 extend = 0;
99 if (len > skip_xx)
100 {
101 len -= skip_xx;
102 goto solid_run;
103 }
104 break;
105 default: /* Intermediate */
106 eol = v & 4;
107 len = (v>>3) + 1 + (extend<<5);
108 extend = 0;
109 if (len > skip_xx)
110 {
111 runp += skip_xx;
112 len -= skip_xx;
113 goto intermediate_run;
114 }
115 runp += len;
116 break;
117 }
118 if (eol)
119 {
120 ww = 0;
121 break;
122 }
123 skip_xx -= len;
124 }
125 while (ww > 0)
126 {
127 int v = *runp++;
128 switch(v & 3)
129 {
130 case 0: /* Extend */
131 extend = v>>2;
132 break;
133 case 1: /* Transparent */
134 len = (v>>2) + 1 + (extend<<6);
135 extend = 0;
136transparent_run:
137 if (len > ww)
138 len = ww;
139 ww -= len;
140 ddp += len * n;
141 break;
142 case 2: /* Solid */
143 eol = v & 4;
144 len = (v>>3) + 1 + (extend<<5);
145 extend = 0;
146solid_run:
147 if (len > ww)
148 len = ww;
149 ww -= len;
150 do
151 {
152#ifdef ALPHA
153#if defined(N) && N == 1
154 IF_OVERPRINT_COMPONENT(0)
155 ddp[0] = FZ_BLEND(colorbv[0], ddp[0], sa);
156#ifdef DA
157 ddp[1] = FZ_BLEND(0xFF, ddp[1], sa);
158 ddp += 2;
159#else
160 ddp++;
161#endif
162#elif defined(N) && N == 3
163 IF_OVERPRINT_COMPONENT(0)
164 ddp[0] = FZ_BLEND(colorbv[0], ddp[0], sa);
165 IF_OVERPRINT_COMPONENT(1)
166 ddp[1] = FZ_BLEND(colorbv[1], ddp[1], sa);
167 IF_OVERPRINT_COMPONENT(2)
168 ddp[2] = FZ_BLEND(colorbv[2], ddp[2], sa);
169#ifdef DA
170 ddp[3] = FZ_BLEND(0xFF, ddp[3], sa);
171 ddp += 4;
172#else
173 ddp += 3;
174#endif
175#elif defined(N) && N == 4
176 IF_OVERPRINT_COMPONENT(0)
177 ddp[0] = FZ_BLEND(colorbv[0], ddp[0], sa);
178 IF_OVERPRINT_COMPONENT(1)
179 ddp[1] = FZ_BLEND(colorbv[1], ddp[1], sa);
180 IF_OVERPRINT_COMPONENT(2)
181 ddp[2] = FZ_BLEND(colorbv[2], ddp[2], sa);
182 IF_OVERPRINT_COMPONENT(3)
183 ddp[3] = FZ_BLEND(colorbv[3], ddp[3], sa);
184#ifdef DA
185 ddp[4] = FZ_BLEND(0xFF, ddp[4], sa);
186 ddp += 5;
187#else
188 ddp += 4;
189#endif
190#else
191 int k = 0;
192 do
193 {
194 IF_OVERPRINT_COMPONENT(k)
195 *ddp = FZ_BLEND(colorbv[k], *ddp, sa);
196 k++;
197 ddp++;
198 }
199 while (k != n1);
200#ifdef DA
201 *ddp = FZ_BLEND(0xFF, *ddp, sa);
202 ddp++;
203#endif
204#endif
205#else
206#if defined(N) && N == 1
207#ifdef DA
208#ifdef EOP
209 IF_OVERPRINT_COMPONENT(0)
210 ddp[0] = colorbv[0];
211 IF_OVERPRINT_COMPONENT(1)
212 *ddp[1] = colorbv[1];
213#else
214 *(uint16_t *)ddp = color;
215#endif
216 ddp += 2;
217#else
218 *ddp++ = colorbv[0];
219#endif
220#elif defined(N) && N == 3
221#ifdef DA
222#ifdef EOP
223 IF_OVERPRINT_COMPONENT(0)
224 ddp[0] = colorbv[0];
225 IF_OVERPRINT_COMPONENT(1)
226 ddp[1] = colorbv[1];
227 IF_OVERPRINT_COMPONENT(2)
228 ddp[2] = colorbv[2];
229 IF_OVERPRINT_COMPONENT(3)
230#else
231 *(uint32_t *)ddp = color;
232#endif
233 ddp += 4;
234#else
235 IF_OVERPRINT_COMPONENT(0)
236 ddp[0] = colorbv[0];
237 IF_OVERPRINT_COMPONENT(1)
238 ddp[1] = colorbv[1];
239 IF_OVERPRINT_COMPONENT(2)
240 ddp[2] = colorbv[2];
241 ddp += 3;
242#endif
243#elif defined(N) && N == 4
244#ifdef DA
245 IF_OVERPRINT_COMPONENT(0)
246 ddp[0] = colorbv[0];
247 IF_OVERPRINT_COMPONENT(1)
248 ddp[1] = colorbv[1];
249 IF_OVERPRINT_COMPONENT(2)
250 ddp[2] = colorbv[2];
251 IF_OVERPRINT_COMPONENT(3)
252 ddp[3] = colorbv[3];
253 ddp[4] = colorbv[4];
254 ddp += 5;
255#else
256#ifdef EOP
257 IF_OVERPRINT_COMPONENT(0)
258 ddp[0] = colorbv[0];
259 IF_OVERPRINT_COMPONENT(1)
260 ddp[1] = colorbv[1];
261 IF_OVERPRINT_COMPONENT(2)
262 ddp[2] = colorbv[2];
263 ddp[3] = colorbv[3];
264#else
265 *(uint32_t *)ddp = color;
266#endif
267 ddp += 4;
268#endif
269#else
270 int k = 0;
271 do
272 {
273 IF_OVERPRINT_COMPONENT(k)
274 *ddp = colorbv[k];
275 k++;
276 ddp++;
277 }
278 while (k != n);
279#endif
280#endif
281 }
282 while (--len);
283 break;
284 default: /* Intermediate */
285 eol = v & 4;
286 len = (v>>3) + 1 + (extend<<5);
287 extend = 0;
288intermediate_run:
289 if (len > ww)
290 len = ww;
291 ww -= len;
292 do
293 {
294 int k = 0;
295 int a = *runp++;
296#ifdef ALPHA
297 a = FZ_COMBINE(sa, FZ_EXPAND(a));
298#else
299 a = FZ_EXPAND(a);
300#endif
301 (void)k;
302#if defined(N) && N == 1
303 IF_OVERPRINT_COMPONENT(0)
304 ddp[0] = FZ_BLEND(colorbv[0], ddp[0], a);
305#ifdef DA
306 ddp[1] = FZ_BLEND(0xFF, ddp[1], a);
307 ddp += 2;
308#else
309 ddp++;
310#endif
311#elif defined(N) && N == 3
312 IF_OVERPRINT_COMPONENT(0)
313 ddp[0] = FZ_BLEND(colorbv[0], ddp[0], a);
314 IF_OVERPRINT_COMPONENT(1)
315 ddp[1] = FZ_BLEND(colorbv[1], ddp[1], a);
316 IF_OVERPRINT_COMPONENT(2)
317 ddp[2] = FZ_BLEND(colorbv[2], ddp[2], a);
318#ifdef DA
319 ddp[3] = FZ_BLEND(0xFF, ddp[3], a);
320 ddp += 4;
321#else
322 ddp += 3;
323#endif
324#elif defined(N) && N == 4
325 IF_OVERPRINT_COMPONENT(0)
326 ddp[0] = FZ_BLEND(colorbv[0], ddp[0], a);
327 IF_OVERPRINT_COMPONENT(1)
328 ddp[1] = FZ_BLEND(colorbv[1], ddp[1], a);
329 IF_OVERPRINT_COMPONENT(2)
330 ddp[2] = FZ_BLEND(colorbv[2], ddp[2], a);
331 IF_OVERPRINT_COMPONENT(3)
332 ddp[3] = FZ_BLEND(colorbv[3], ddp[3], a);
333#ifdef DA
334 ddp[4] = FZ_BLEND(0xFF, ddp[4], a);
335 ddp += 5;
336#else
337 ddp += 4;
338#endif
339#else
340 do
341 {
342 IF_OVERPRINT_COMPONENT(k)
343 *ddp = FZ_BLEND(colorbv[k], *ddp, a);
344 k++;
345 ddp++;
346 }
347 while (k != n1);
348#ifdef DA
349 *ddp = FZ_BLEND(0xFF, *ddp, a);
350 ddp++;
351#endif
352#endif
353 }
354 while (--len);
355 break;
356 }
357 if (eol)
358 break;
359 }
360 }
361 dp += span;
362 }
363}
364
365#undef NAME
366#undef ALPHA
367#undef NAME2
368#undef NAME3
369#undef EOP
370#undef DA
371#undef N
372#undef FUNCTION_NAMER
373#undef FUNCTION_NAME
374#undef IF_OVERPRINT_COMPONENT
375