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 | |
33 | static inline void |
34 | FUNCTION_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; |
136 | transparent_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; |
146 | solid_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; |
288 | intermediate_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 | |