|
1 #ifdef HAVE_CONFIG_H |
|
2 #include <config.h> |
|
3 #endif |
|
4 |
|
5 #include <math.h> |
|
6 #include <string.h> |
|
7 |
|
8 #include "pixman-private.h" |
|
9 |
|
10 #include "pixman-combine.h" |
|
11 |
|
12 /*** per channel helper functions ***/ |
|
13 |
|
14 static void |
|
15 combine_mask_ca (comp4_t *src, comp4_t *mask) |
|
16 { |
|
17 comp4_t a = *mask; |
|
18 |
|
19 comp4_t x; |
|
20 comp2_t xa; |
|
21 |
|
22 if (!a) |
|
23 { |
|
24 *(src) = 0; |
|
25 return; |
|
26 } |
|
27 |
|
28 x = *(src); |
|
29 if (a == ~0) |
|
30 { |
|
31 x = x >> A_SHIFT; |
|
32 x |= x << G_SHIFT; |
|
33 x |= x << R_SHIFT; |
|
34 *(mask) = x; |
|
35 return; |
|
36 } |
|
37 |
|
38 xa = x >> A_SHIFT; |
|
39 UNcx4_MUL_UNcx4 (x, a); |
|
40 *(src) = x; |
|
41 |
|
42 UNcx4_MUL_UNc (a, xa); |
|
43 *(mask) = a; |
|
44 } |
|
45 |
|
46 static void |
|
47 combine_mask_value_ca (comp4_t *src, const comp4_t *mask) |
|
48 { |
|
49 comp4_t a = *mask; |
|
50 comp4_t x; |
|
51 |
|
52 if (!a) |
|
53 { |
|
54 *(src) = 0; |
|
55 return; |
|
56 } |
|
57 |
|
58 if (a == ~0) |
|
59 return; |
|
60 |
|
61 x = *(src); |
|
62 UNcx4_MUL_UNcx4 (x, a); |
|
63 *(src) = x; |
|
64 } |
|
65 |
|
66 static void |
|
67 combine_mask_alpha_ca (const comp4_t *src, comp4_t *mask) |
|
68 { |
|
69 comp4_t a = *(mask); |
|
70 comp4_t x; |
|
71 |
|
72 if (!a) |
|
73 return; |
|
74 |
|
75 x = *(src) >> A_SHIFT; |
|
76 if (x == MASK) |
|
77 return; |
|
78 |
|
79 if (a == ~0) |
|
80 { |
|
81 x |= x << G_SHIFT; |
|
82 x |= x << R_SHIFT; |
|
83 *(mask) = x; |
|
84 return; |
|
85 } |
|
86 |
|
87 UNcx4_MUL_UNc (a, x); |
|
88 *(mask) = a; |
|
89 } |
|
90 |
|
91 /* |
|
92 * There are two ways of handling alpha -- either as a single unified value or |
|
93 * a separate value for each component, hence each macro must have two |
|
94 * versions. The unified alpha version has a 'U' at the end of the name, |
|
95 * the component version has a 'C'. Similarly, functions which deal with |
|
96 * this difference will have two versions using the same convention. |
|
97 */ |
|
98 |
|
99 /* |
|
100 * All of the composing functions |
|
101 */ |
|
102 |
|
103 static force_inline comp4_t |
|
104 combine_mask (const comp4_t *src, const comp4_t *mask, int i) |
|
105 { |
|
106 comp4_t s, m; |
|
107 |
|
108 if (mask) |
|
109 { |
|
110 m = *(mask + i) >> A_SHIFT; |
|
111 |
|
112 if (!m) |
|
113 return 0; |
|
114 } |
|
115 |
|
116 s = *(src + i); |
|
117 |
|
118 if (mask) |
|
119 UNcx4_MUL_UNc (s, m); |
|
120 |
|
121 return s; |
|
122 } |
|
123 |
|
124 static void |
|
125 combine_clear (pixman_implementation_t *imp, |
|
126 pixman_op_t op, |
|
127 comp4_t * dest, |
|
128 const comp4_t * src, |
|
129 const comp4_t * mask, |
|
130 int width) |
|
131 { |
|
132 memset (dest, 0, width * sizeof(comp4_t)); |
|
133 } |
|
134 |
|
135 static void |
|
136 combine_dst (pixman_implementation_t *imp, |
|
137 pixman_op_t op, |
|
138 comp4_t * dest, |
|
139 const comp4_t * src, |
|
140 const comp4_t * mask, |
|
141 int width) |
|
142 { |
|
143 return; |
|
144 } |
|
145 |
|
146 static void |
|
147 combine_src_u (pixman_implementation_t *imp, |
|
148 pixman_op_t op, |
|
149 comp4_t * dest, |
|
150 const comp4_t * src, |
|
151 const comp4_t * mask, |
|
152 int width) |
|
153 { |
|
154 int i; |
|
155 |
|
156 if (!mask) |
|
157 memcpy (dest, src, width * sizeof (comp4_t)); |
|
158 else |
|
159 { |
|
160 for (i = 0; i < width; ++i) |
|
161 { |
|
162 comp4_t s = combine_mask (src, mask, i); |
|
163 |
|
164 *(dest + i) = s; |
|
165 } |
|
166 } |
|
167 } |
|
168 |
|
169 /* if the Src is opaque, call combine_src_u */ |
|
170 static void |
|
171 combine_over_u (pixman_implementation_t *imp, |
|
172 pixman_op_t op, |
|
173 comp4_t * dest, |
|
174 const comp4_t * src, |
|
175 const comp4_t * mask, |
|
176 int width) |
|
177 { |
|
178 int i; |
|
179 |
|
180 for (i = 0; i < width; ++i) |
|
181 { |
|
182 comp4_t s = combine_mask (src, mask, i); |
|
183 comp4_t d = *(dest + i); |
|
184 comp4_t ia = ALPHA_c (~s); |
|
185 |
|
186 UNcx4_MUL_UNc_ADD_UNcx4 (d, ia, s); |
|
187 *(dest + i) = d; |
|
188 } |
|
189 } |
|
190 |
|
191 /* if the Dst is opaque, this is a noop */ |
|
192 static void |
|
193 combine_over_reverse_u (pixman_implementation_t *imp, |
|
194 pixman_op_t op, |
|
195 comp4_t * dest, |
|
196 const comp4_t * src, |
|
197 const comp4_t * mask, |
|
198 int width) |
|
199 { |
|
200 int i; |
|
201 |
|
202 for (i = 0; i < width; ++i) |
|
203 { |
|
204 comp4_t s = combine_mask (src, mask, i); |
|
205 comp4_t d = *(dest + i); |
|
206 comp4_t ia = ALPHA_c (~*(dest + i)); |
|
207 UNcx4_MUL_UNc_ADD_UNcx4 (s, ia, d); |
|
208 *(dest + i) = s; |
|
209 } |
|
210 } |
|
211 |
|
212 /* if the Dst is opaque, call combine_src_u */ |
|
213 static void |
|
214 combine_in_u (pixman_implementation_t *imp, |
|
215 pixman_op_t op, |
|
216 comp4_t * dest, |
|
217 const comp4_t * src, |
|
218 const comp4_t * mask, |
|
219 int width) |
|
220 { |
|
221 int i; |
|
222 |
|
223 for (i = 0; i < width; ++i) |
|
224 { |
|
225 comp4_t s = combine_mask (src, mask, i); |
|
226 comp4_t a = ALPHA_c (*(dest + i)); |
|
227 UNcx4_MUL_UNc (s, a); |
|
228 *(dest + i) = s; |
|
229 } |
|
230 } |
|
231 |
|
232 /* if the Src is opaque, this is a noop */ |
|
233 static void |
|
234 combine_in_reverse_u (pixman_implementation_t *imp, |
|
235 pixman_op_t op, |
|
236 comp4_t * dest, |
|
237 const comp4_t * src, |
|
238 const comp4_t * mask, |
|
239 int width) |
|
240 { |
|
241 int i; |
|
242 |
|
243 for (i = 0; i < width; ++i) |
|
244 { |
|
245 comp4_t s = combine_mask (src, mask, i); |
|
246 comp4_t d = *(dest + i); |
|
247 comp4_t a = ALPHA_c (s); |
|
248 UNcx4_MUL_UNc (d, a); |
|
249 *(dest + i) = d; |
|
250 } |
|
251 } |
|
252 |
|
253 /* if the Dst is opaque, call combine_clear */ |
|
254 static void |
|
255 combine_out_u (pixman_implementation_t *imp, |
|
256 pixman_op_t op, |
|
257 comp4_t * dest, |
|
258 const comp4_t * src, |
|
259 const comp4_t * mask, |
|
260 int width) |
|
261 { |
|
262 int i; |
|
263 |
|
264 for (i = 0; i < width; ++i) |
|
265 { |
|
266 comp4_t s = combine_mask (src, mask, i); |
|
267 comp4_t a = ALPHA_c (~*(dest + i)); |
|
268 UNcx4_MUL_UNc (s, a); |
|
269 *(dest + i) = s; |
|
270 } |
|
271 } |
|
272 |
|
273 /* if the Src is opaque, call combine_clear */ |
|
274 static void |
|
275 combine_out_reverse_u (pixman_implementation_t *imp, |
|
276 pixman_op_t op, |
|
277 comp4_t * dest, |
|
278 const comp4_t * src, |
|
279 const comp4_t * mask, |
|
280 int width) |
|
281 { |
|
282 int i; |
|
283 |
|
284 for (i = 0; i < width; ++i) |
|
285 { |
|
286 comp4_t s = combine_mask (src, mask, i); |
|
287 comp4_t d = *(dest + i); |
|
288 comp4_t a = ALPHA_c (~s); |
|
289 UNcx4_MUL_UNc (d, a); |
|
290 *(dest + i) = d; |
|
291 } |
|
292 } |
|
293 |
|
294 /* if the Src is opaque, call combine_in_u */ |
|
295 /* if the Dst is opaque, call combine_over_u */ |
|
296 /* if both the Src and Dst are opaque, call combine_src_u */ |
|
297 static void |
|
298 combine_atop_u (pixman_implementation_t *imp, |
|
299 pixman_op_t op, |
|
300 comp4_t * dest, |
|
301 const comp4_t * src, |
|
302 const comp4_t * mask, |
|
303 int width) |
|
304 { |
|
305 int i; |
|
306 |
|
307 for (i = 0; i < width; ++i) |
|
308 { |
|
309 comp4_t s = combine_mask (src, mask, i); |
|
310 comp4_t d = *(dest + i); |
|
311 comp4_t dest_a = ALPHA_c (d); |
|
312 comp4_t src_ia = ALPHA_c (~s); |
|
313 |
|
314 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (s, dest_a, d, src_ia); |
|
315 *(dest + i) = s; |
|
316 } |
|
317 } |
|
318 |
|
319 /* if the Src is opaque, call combine_over_reverse_u */ |
|
320 /* if the Dst is opaque, call combine_in_reverse_u */ |
|
321 /* if both the Src and Dst are opaque, call combine_dst_u */ |
|
322 static void |
|
323 combine_atop_reverse_u (pixman_implementation_t *imp, |
|
324 pixman_op_t op, |
|
325 comp4_t * dest, |
|
326 const comp4_t * src, |
|
327 const comp4_t * mask, |
|
328 int width) |
|
329 { |
|
330 int i; |
|
331 |
|
332 for (i = 0; i < width; ++i) |
|
333 { |
|
334 comp4_t s = combine_mask (src, mask, i); |
|
335 comp4_t d = *(dest + i); |
|
336 comp4_t src_a = ALPHA_c (s); |
|
337 comp4_t dest_ia = ALPHA_c (~d); |
|
338 |
|
339 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (s, dest_ia, d, src_a); |
|
340 *(dest + i) = s; |
|
341 } |
|
342 } |
|
343 |
|
344 /* if the Src is opaque, call combine_over_u */ |
|
345 /* if the Dst is opaque, call combine_over_reverse_u */ |
|
346 /* if both the Src and Dst are opaque, call combine_clear */ |
|
347 static void |
|
348 combine_xor_u (pixman_implementation_t *imp, |
|
349 pixman_op_t op, |
|
350 comp4_t * dest, |
|
351 const comp4_t * src, |
|
352 const comp4_t * mask, |
|
353 int width) |
|
354 { |
|
355 int i; |
|
356 |
|
357 for (i = 0; i < width; ++i) |
|
358 { |
|
359 comp4_t s = combine_mask (src, mask, i); |
|
360 comp4_t d = *(dest + i); |
|
361 comp4_t src_ia = ALPHA_c (~s); |
|
362 comp4_t dest_ia = ALPHA_c (~d); |
|
363 |
|
364 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (s, dest_ia, d, src_ia); |
|
365 *(dest + i) = s; |
|
366 } |
|
367 } |
|
368 |
|
369 static void |
|
370 combine_add_u (pixman_implementation_t *imp, |
|
371 pixman_op_t op, |
|
372 comp4_t * dest, |
|
373 const comp4_t * src, |
|
374 const comp4_t * mask, |
|
375 int width) |
|
376 { |
|
377 int i; |
|
378 |
|
379 for (i = 0; i < width; ++i) |
|
380 { |
|
381 comp4_t s = combine_mask (src, mask, i); |
|
382 comp4_t d = *(dest + i); |
|
383 UNcx4_ADD_UNcx4 (d, s); |
|
384 *(dest + i) = d; |
|
385 } |
|
386 } |
|
387 |
|
388 /* if the Src is opaque, call combine_add_u */ |
|
389 /* if the Dst is opaque, call combine_add_u */ |
|
390 /* if both the Src and Dst are opaque, call combine_add_u */ |
|
391 static void |
|
392 combine_saturate_u (pixman_implementation_t *imp, |
|
393 pixman_op_t op, |
|
394 comp4_t * dest, |
|
395 const comp4_t * src, |
|
396 const comp4_t * mask, |
|
397 int width) |
|
398 { |
|
399 int i; |
|
400 |
|
401 for (i = 0; i < width; ++i) |
|
402 { |
|
403 comp4_t s = combine_mask (src, mask, i); |
|
404 comp4_t d = *(dest + i); |
|
405 comp2_t sa, da; |
|
406 |
|
407 sa = s >> A_SHIFT; |
|
408 da = ~d >> A_SHIFT; |
|
409 if (sa > da) |
|
410 { |
|
411 sa = DIV_UNc (da, sa); |
|
412 UNcx4_MUL_UNc (s, sa); |
|
413 } |
|
414 ; |
|
415 UNcx4_ADD_UNcx4 (d, s); |
|
416 *(dest + i) = d; |
|
417 } |
|
418 } |
|
419 |
|
420 /* |
|
421 * PDF blend modes: |
|
422 * The following blend modes have been taken from the PDF ISO 32000 |
|
423 * specification, which at this point in time is available from |
|
424 * http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf |
|
425 * The relevant chapters are 11.3.5 and 11.3.6. |
|
426 * The formula for computing the final pixel color given in 11.3.6 is: |
|
427 * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs) |
|
428 * with B() being the blend function. |
|
429 * Note that OVER is a special case of this operation, using B(Cb, Cs) = Cs |
|
430 * |
|
431 * These blend modes should match the SVG filter draft specification, as |
|
432 * it has been designed to mirror ISO 32000. Note that at the current point |
|
433 * no released draft exists that shows this, as the formulas have not been |
|
434 * updated yet after the release of ISO 32000. |
|
435 * |
|
436 * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and |
|
437 * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an |
|
438 * argument. Note that this implementation operates on premultiplied colors, |
|
439 * while the PDF specification does not. Therefore the code uses the formula |
|
440 * Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as) |
|
441 */ |
|
442 |
|
443 /* |
|
444 * Multiply |
|
445 * B(Dca, ad, Sca, as) = Dca.Sca |
|
446 */ |
|
447 |
|
448 static void |
|
449 combine_multiply_u (pixman_implementation_t *imp, |
|
450 pixman_op_t op, |
|
451 comp4_t * dest, |
|
452 const comp4_t * src, |
|
453 const comp4_t * mask, |
|
454 int width) |
|
455 { |
|
456 int i; |
|
457 |
|
458 for (i = 0; i < width; ++i) |
|
459 { |
|
460 comp4_t s = combine_mask (src, mask, i); |
|
461 comp4_t d = *(dest + i); |
|
462 comp4_t ss = s; |
|
463 comp4_t src_ia = ALPHA_c (~s); |
|
464 comp4_t dest_ia = ALPHA_c (~d); |
|
465 |
|
466 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (ss, dest_ia, d, src_ia); |
|
467 UNcx4_MUL_UNcx4 (d, s); |
|
468 UNcx4_ADD_UNcx4 (d, ss); |
|
469 |
|
470 *(dest + i) = d; |
|
471 } |
|
472 } |
|
473 |
|
474 static void |
|
475 combine_multiply_ca (pixman_implementation_t *imp, |
|
476 pixman_op_t op, |
|
477 comp4_t * dest, |
|
478 const comp4_t * src, |
|
479 const comp4_t * mask, |
|
480 int width) |
|
481 { |
|
482 int i; |
|
483 |
|
484 for (i = 0; i < width; ++i) |
|
485 { |
|
486 comp4_t m = *(mask + i); |
|
487 comp4_t s = *(src + i); |
|
488 comp4_t d = *(dest + i); |
|
489 comp4_t r = d; |
|
490 comp4_t dest_ia = ALPHA_c (~d); |
|
491 |
|
492 combine_mask_value_ca (&s, &m); |
|
493 |
|
494 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (r, ~m, s, dest_ia); |
|
495 UNcx4_MUL_UNcx4 (d, s); |
|
496 UNcx4_ADD_UNcx4 (r, d); |
|
497 |
|
498 *(dest + i) = r; |
|
499 } |
|
500 } |
|
501 |
|
502 #define PDF_SEPARABLE_BLEND_MODE(name) \ |
|
503 static void \ |
|
504 combine_ ## name ## _u (pixman_implementation_t *imp, \ |
|
505 pixman_op_t op, \ |
|
506 comp4_t * dest, \ |
|
507 const comp4_t * src, \ |
|
508 const comp4_t * mask, \ |
|
509 int width) \ |
|
510 { \ |
|
511 int i; \ |
|
512 for (i = 0; i < width; ++i) { \ |
|
513 comp4_t s = combine_mask (src, mask, i); \ |
|
514 comp4_t d = *(dest + i); \ |
|
515 comp1_t sa = ALPHA_c (s); \ |
|
516 comp1_t isa = ~sa; \ |
|
517 comp1_t da = ALPHA_c (d); \ |
|
518 comp1_t ida = ~da; \ |
|
519 comp4_t result; \ |
|
520 \ |
|
521 result = d; \ |
|
522 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida); \ |
|
523 \ |
|
524 *(dest + i) = result + \ |
|
525 (DIV_ONE_UNc (sa * (comp4_t)da) << A_SHIFT) + \ |
|
526 (blend_ ## name (RED_c (d), da, RED_c (s), sa) << R_SHIFT) + \ |
|
527 (blend_ ## name (GREEN_c (d), da, GREEN_c (s), sa) << G_SHIFT) + \ |
|
528 (blend_ ## name (BLUE_c (d), da, BLUE_c (s), sa)); \ |
|
529 } \ |
|
530 } \ |
|
531 \ |
|
532 static void \ |
|
533 combine_ ## name ## _ca (pixman_implementation_t *imp, \ |
|
534 pixman_op_t op, \ |
|
535 comp4_t * dest, \ |
|
536 const comp4_t * src, \ |
|
537 const comp4_t * mask, \ |
|
538 int width) \ |
|
539 { \ |
|
540 int i; \ |
|
541 for (i = 0; i < width; ++i) { \ |
|
542 comp4_t m = *(mask + i); \ |
|
543 comp4_t s = *(src + i); \ |
|
544 comp4_t d = *(dest + i); \ |
|
545 comp1_t da = ALPHA_c (d); \ |
|
546 comp1_t ida = ~da; \ |
|
547 comp4_t result; \ |
|
548 \ |
|
549 combine_mask_value_ca (&s, &m); \ |
|
550 \ |
|
551 result = d; \ |
|
552 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (result, ~m, s, ida); \ |
|
553 \ |
|
554 result += \ |
|
555 (DIV_ONE_UNc (ALPHA_c (m) * (comp4_t)da) << A_SHIFT) + \ |
|
556 (blend_ ## name (RED_c (d), da, RED_c (s), RED_c (m)) << R_SHIFT) + \ |
|
557 (blend_ ## name (GREEN_c (d), da, GREEN_c (s), GREEN_c (m)) << G_SHIFT) + \ |
|
558 (blend_ ## name (BLUE_c (d), da, BLUE_c (s), BLUE_c (m))); \ |
|
559 \ |
|
560 *(dest + i) = result; \ |
|
561 } \ |
|
562 } |
|
563 |
|
564 /* |
|
565 * Screen |
|
566 * B(Dca, ad, Sca, as) = Dca.sa + Sca.da - Dca.Sca |
|
567 */ |
|
568 static inline comp4_t |
|
569 blend_screen (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa) |
|
570 { |
|
571 return DIV_ONE_UNc (sca * da + dca * sa - sca * dca); |
|
572 } |
|
573 |
|
574 PDF_SEPARABLE_BLEND_MODE (screen) |
|
575 |
|
576 /* |
|
577 * Overlay |
|
578 * B(Dca, Da, Sca, Sa) = |
|
579 * if 2.Dca < Da |
|
580 * 2.Sca.Dca |
|
581 * otherwise |
|
582 * Sa.Da - 2.(Da - Dca).(Sa - Sca) |
|
583 */ |
|
584 static inline comp4_t |
|
585 blend_overlay (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa) |
|
586 { |
|
587 comp4_t rca; |
|
588 |
|
589 if (2 * dca < da) |
|
590 rca = 2 * sca * dca; |
|
591 else |
|
592 rca = sa * da - 2 * (da - dca) * (sa - sca); |
|
593 return DIV_ONE_UNc (rca); |
|
594 } |
|
595 |
|
596 PDF_SEPARABLE_BLEND_MODE (overlay) |
|
597 |
|
598 /* |
|
599 * Darken |
|
600 * B(Dca, Da, Sca, Sa) = min (Sca.Da, Dca.Sa) |
|
601 */ |
|
602 static inline comp4_t |
|
603 blend_darken (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa) |
|
604 { |
|
605 comp4_t s, d; |
|
606 |
|
607 s = sca * da; |
|
608 d = dca * sa; |
|
609 return DIV_ONE_UNc (s > d ? d : s); |
|
610 } |
|
611 |
|
612 PDF_SEPARABLE_BLEND_MODE (darken) |
|
613 |
|
614 /* |
|
615 * Lighten |
|
616 * B(Dca, Da, Sca, Sa) = max (Sca.Da, Dca.Sa) |
|
617 */ |
|
618 static inline comp4_t |
|
619 blend_lighten (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa) |
|
620 { |
|
621 comp4_t s, d; |
|
622 |
|
623 s = sca * da; |
|
624 d = dca * sa; |
|
625 return DIV_ONE_UNc (s > d ? s : d); |
|
626 } |
|
627 |
|
628 PDF_SEPARABLE_BLEND_MODE (lighten) |
|
629 |
|
630 /* |
|
631 * Color dodge |
|
632 * B(Dca, Da, Sca, Sa) = |
|
633 * if Dca == 0 |
|
634 * 0 |
|
635 * if Sca == Sa |
|
636 * Sa.Da |
|
637 * otherwise |
|
638 * Sa.Da. min (1, Dca / Da / (1 - Sca/Sa)) |
|
639 */ |
|
640 static inline comp4_t |
|
641 blend_color_dodge (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa) |
|
642 { |
|
643 if (sca >= sa) |
|
644 { |
|
645 return dca == 0 ? 0 : DIV_ONE_UNc (sa * da); |
|
646 } |
|
647 else |
|
648 { |
|
649 comp4_t rca = dca * sa / (sa - sca); |
|
650 return DIV_ONE_UNc (sa * MIN (rca, da)); |
|
651 } |
|
652 } |
|
653 |
|
654 PDF_SEPARABLE_BLEND_MODE (color_dodge) |
|
655 |
|
656 /* |
|
657 * Color burn |
|
658 * B(Dca, Da, Sca, Sa) = |
|
659 * if Dca == Da |
|
660 * Sa.Da |
|
661 * if Sca == 0 |
|
662 * 0 |
|
663 * otherwise |
|
664 * Sa.Da.(1 - min (1, (1 - Dca/Da).Sa / Sca)) |
|
665 */ |
|
666 static inline comp4_t |
|
667 blend_color_burn (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa) |
|
668 { |
|
669 if (sca == 0) |
|
670 { |
|
671 return dca < da ? 0 : DIV_ONE_UNc (sa * da); |
|
672 } |
|
673 else |
|
674 { |
|
675 comp4_t rca = (da - dca) * sa / sca; |
|
676 return DIV_ONE_UNc (sa * (MAX (rca, da) - rca)); |
|
677 } |
|
678 } |
|
679 |
|
680 PDF_SEPARABLE_BLEND_MODE (color_burn) |
|
681 |
|
682 /* |
|
683 * Hard light |
|
684 * B(Dca, Da, Sca, Sa) = |
|
685 * if 2.Sca < Sa |
|
686 * 2.Sca.Dca |
|
687 * otherwise |
|
688 * Sa.Da - 2.(Da - Dca).(Sa - Sca) |
|
689 */ |
|
690 static inline comp4_t |
|
691 blend_hard_light (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa) |
|
692 { |
|
693 if (2 * sca < sa) |
|
694 return DIV_ONE_UNc (2 * sca * dca); |
|
695 else |
|
696 return DIV_ONE_UNc (sa * da - 2 * (da - dca) * (sa - sca)); |
|
697 } |
|
698 |
|
699 PDF_SEPARABLE_BLEND_MODE (hard_light) |
|
700 |
|
701 /* |
|
702 * Soft light |
|
703 * B(Dca, Da, Sca, Sa) = |
|
704 * if (2.Sca <= Sa) |
|
705 * Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa)) |
|
706 * otherwise if Dca.4 <= Da |
|
707 * Dca.(Sa + (2.Sca - Sa).((16.Dca/Da - 12).Dca/Da + 3) |
|
708 * otherwise |
|
709 * (Dca.Sa + (SQRT (Dca/Da).Da - Dca).(2.Sca - Sa)) |
|
710 */ |
|
711 static inline comp4_t |
|
712 blend_soft_light (comp4_t dca_org, |
|
713 comp4_t da_org, |
|
714 comp4_t sca_org, |
|
715 comp4_t sa_org) |
|
716 { |
|
717 double dca = dca_org * (1.0 / MASK); |
|
718 double da = da_org * (1.0 / MASK); |
|
719 double sca = sca_org * (1.0 / MASK); |
|
720 double sa = sa_org * (1.0 / MASK); |
|
721 double rca; |
|
722 |
|
723 if (2 * sca < sa) |
|
724 { |
|
725 if (da == 0) |
|
726 rca = dca * sa; |
|
727 else |
|
728 rca = dca * sa - dca * (da - dca) * (sa - 2 * sca) / da; |
|
729 } |
|
730 else if (da == 0) |
|
731 { |
|
732 rca = 0; |
|
733 } |
|
734 else if (4 * dca <= da) |
|
735 { |
|
736 rca = dca * sa + |
|
737 (2 * sca - sa) * dca * ((16 * dca / da - 12) * dca / da + 3); |
|
738 } |
|
739 else |
|
740 { |
|
741 rca = dca * sa + (sqrt (dca * da) - dca) * (2 * sca - sa); |
|
742 } |
|
743 return rca * MASK + 0.5; |
|
744 } |
|
745 |
|
746 PDF_SEPARABLE_BLEND_MODE (soft_light) |
|
747 |
|
748 /* |
|
749 * Difference |
|
750 * B(Dca, Da, Sca, Sa) = abs (Dca.Sa - Sca.Da) |
|
751 */ |
|
752 static inline comp4_t |
|
753 blend_difference (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa) |
|
754 { |
|
755 comp4_t dcasa = dca * sa; |
|
756 comp4_t scada = sca * da; |
|
757 |
|
758 if (scada < dcasa) |
|
759 return DIV_ONE_UNc (dcasa - scada); |
|
760 else |
|
761 return DIV_ONE_UNc (scada - dcasa); |
|
762 } |
|
763 |
|
764 PDF_SEPARABLE_BLEND_MODE (difference) |
|
765 |
|
766 /* |
|
767 * Exclusion |
|
768 * B(Dca, Da, Sca, Sa) = (Sca.Da + Dca.Sa - 2.Sca.Dca) |
|
769 */ |
|
770 |
|
771 /* This can be made faster by writing it directly and not using |
|
772 * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */ |
|
773 |
|
774 static inline comp4_t |
|
775 blend_exclusion (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa) |
|
776 { |
|
777 return DIV_ONE_UNc (sca * da + dca * sa - 2 * dca * sca); |
|
778 } |
|
779 |
|
780 PDF_SEPARABLE_BLEND_MODE (exclusion) |
|
781 |
|
782 #undef PDF_SEPARABLE_BLEND_MODE |
|
783 |
|
784 /* |
|
785 * PDF nonseperable blend modes are implemented using the following functions |
|
786 * to operate in Hsl space, with Cmax, Cmid, Cmin referring to the max, mid |
|
787 * and min value of the red, green and blue components. |
|
788 * |
|
789 * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue |
|
790 * |
|
791 * clip_color (C): |
|
792 * l = LUM (C) |
|
793 * min = Cmin |
|
794 * max = Cmax |
|
795 * if n < 0.0 |
|
796 * C = l + ( ( ( C – l ) × l ) ⁄ ( l – min ) ) |
|
797 * if x > 1.0 |
|
798 * C = l + ( ( ( C – l ) × ( 1 – l ) ) ⁄ ( max – l ) ) |
|
799 * return C |
|
800 * |
|
801 * set_lum (C, l): |
|
802 * d = l – LUM (C) |
|
803 * C += d |
|
804 * return clip_color (C) |
|
805 * |
|
806 * SAT (C) = CH_MAX (C) - CH_MIN (C) |
|
807 * |
|
808 * set_sat (C, s): |
|
809 * if Cmax > Cmin |
|
810 * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) ) |
|
811 * Cmax = s |
|
812 * else |
|
813 * Cmid = Cmax = 0.0 |
|
814 * Cmin = 0.0 |
|
815 * return C |
|
816 */ |
|
817 |
|
818 /* For premultiplied colors, we need to know what happens when C is |
|
819 * multiplied by a real number. LUM and SAT are linear: |
|
820 * |
|
821 * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C) |
|
822 * |
|
823 * If we extend clip_color with an extra argument a and change |
|
824 * |
|
825 * if x >= 1.0 |
|
826 * |
|
827 * into |
|
828 * |
|
829 * if x >= a |
|
830 * |
|
831 * then clip_color is also linear: |
|
832 * |
|
833 * r * clip_color (C, a) = clip_color (r_c, ra); |
|
834 * |
|
835 * for positive r. |
|
836 * |
|
837 * Similarly, we can extend set_lum with an extra argument that is just passed |
|
838 * on to clip_color: |
|
839 * |
|
840 * r * set_lum ( C, l, a) |
|
841 * |
|
842 * = r × clip_color ( C + l - LUM (C), a) |
|
843 * |
|
844 * = clip_color ( r * C + r × l - r * LUM (C), r * a) |
|
845 * |
|
846 * = set_lum ( r * C, r * l, r * a) |
|
847 * |
|
848 * Finally, set_sat: |
|
849 * |
|
850 * r * set_sat (C, s) = set_sat (x * C, r * s) |
|
851 * |
|
852 * The above holds for all non-zero x, because the x'es in the fraction for |
|
853 * C_mid cancel out. Specifically, it holds for x = r: |
|
854 * |
|
855 * r * set_sat (C, s) = set_sat (r_c, rs) |
|
856 * |
|
857 */ |
|
858 |
|
859 /* So, for the non-separable PDF blend modes, we have (using s, d for |
|
860 * non-premultiplied colors, and S, D for premultiplied: |
|
861 * |
|
862 * Color: |
|
863 * |
|
864 * a_s * a_d * B(s, d) |
|
865 * = a_s * a_d * set_lum (S/a_s, LUM (D/a_d), 1) |
|
866 * = set_lum (S * a_d, a_s * LUM (D), a_s * a_d) |
|
867 * |
|
868 * |
|
869 * Luminosity: |
|
870 * |
|
871 * a_s * a_d * B(s, d) |
|
872 * = a_s * a_d * set_lum (D/a_d, LUM(S/a_s), 1) |
|
873 * = set_lum (a_s * D, a_d * LUM(S), a_s * a_d) |
|
874 * |
|
875 * |
|
876 * Saturation: |
|
877 * |
|
878 * a_s * a_d * B(s, d) |
|
879 * = a_s * a_d * set_lum (set_sat (D/a_d, SAT (S/a_s)), LUM (D/a_d), 1) |
|
880 * = set_lum (a_s * a_d * set_sat (D/a_d, SAT (S/a_s)), |
|
881 * a_s * LUM (D), a_s * a_d) |
|
882 * = set_lum (set_sat (a_s * D, a_d * SAT (S), a_s * LUM (D), a_s * a_d)) |
|
883 * |
|
884 * Hue: |
|
885 * |
|
886 * a_s * a_d * B(s, d) |
|
887 * = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1) |
|
888 * = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d) |
|
889 * |
|
890 */ |
|
891 |
|
892 #define CH_MIN(c) (c[0] < c[1] ? (c[0] < c[2] ? c[0] : c[2]) : (c[1] < c[2] ? c[1] : c[2])) |
|
893 #define CH_MAX(c) (c[0] > c[1] ? (c[0] > c[2] ? c[0] : c[2]) : (c[1] > c[2] ? c[1] : c[2])) |
|
894 #define LUM(c) ((c[0] * 30 + c[1] * 59 + c[2] * 11) / 100) |
|
895 #define SAT(c) (CH_MAX (c) - CH_MIN (c)) |
|
896 |
|
897 #define PDF_NON_SEPARABLE_BLEND_MODE(name) \ |
|
898 static void \ |
|
899 combine_ ## name ## _u (pixman_implementation_t *imp, \ |
|
900 pixman_op_t op, \ |
|
901 comp4_t *dest, \ |
|
902 const comp4_t *src, \ |
|
903 const comp4_t *mask, \ |
|
904 int width) \ |
|
905 { \ |
|
906 int i; \ |
|
907 for (i = 0; i < width; ++i) \ |
|
908 { \ |
|
909 comp4_t s = combine_mask (src, mask, i); \ |
|
910 comp4_t d = *(dest + i); \ |
|
911 comp1_t sa = ALPHA_c (s); \ |
|
912 comp1_t isa = ~sa; \ |
|
913 comp1_t da = ALPHA_c (d); \ |
|
914 comp1_t ida = ~da; \ |
|
915 comp4_t result; \ |
|
916 comp4_t sc[3], dc[3], c[3]; \ |
|
917 \ |
|
918 result = d; \ |
|
919 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida); \ |
|
920 dc[0] = RED_c (d); \ |
|
921 sc[0] = RED_c (s); \ |
|
922 dc[1] = GREEN_c (d); \ |
|
923 sc[1] = GREEN_c (s); \ |
|
924 dc[2] = BLUE_c (d); \ |
|
925 sc[2] = BLUE_c (s); \ |
|
926 blend_ ## name (c, dc, da, sc, sa); \ |
|
927 \ |
|
928 *(dest + i) = result + \ |
|
929 (DIV_ONE_UNc (sa * (comp4_t)da) << A_SHIFT) + \ |
|
930 (DIV_ONE_UNc (c[0]) << R_SHIFT) + \ |
|
931 (DIV_ONE_UNc (c[1]) << G_SHIFT) + \ |
|
932 (DIV_ONE_UNc (c[2])); \ |
|
933 } \ |
|
934 } |
|
935 |
|
936 static void |
|
937 set_lum (comp4_t dest[3], comp4_t src[3], comp4_t sa, comp4_t lum) |
|
938 { |
|
939 double a, l, min, max; |
|
940 double tmp[3]; |
|
941 |
|
942 a = sa * (1.0 / MASK); |
|
943 |
|
944 l = lum * (1.0 / MASK); |
|
945 tmp[0] = src[0] * (1.0 / MASK); |
|
946 tmp[1] = src[1] * (1.0 / MASK); |
|
947 tmp[2] = src[2] * (1.0 / MASK); |
|
948 |
|
949 l = l - LUM (tmp); |
|
950 tmp[0] += l; |
|
951 tmp[1] += l; |
|
952 tmp[2] += l; |
|
953 |
|
954 /* clip_color */ |
|
955 l = LUM (tmp); |
|
956 min = CH_MIN (tmp); |
|
957 max = CH_MAX (tmp); |
|
958 |
|
959 if (min < 0) |
|
960 { |
|
961 if (l - min == 0.0) |
|
962 { |
|
963 tmp[0] = 0; |
|
964 tmp[1] = 0; |
|
965 tmp[2] = 0; |
|
966 } |
|
967 else |
|
968 { |
|
969 tmp[0] = l + (tmp[0] - l) * l / (l - min); |
|
970 tmp[1] = l + (tmp[1] - l) * l / (l - min); |
|
971 tmp[2] = l + (tmp[2] - l) * l / (l - min); |
|
972 } |
|
973 } |
|
974 if (max > a) |
|
975 { |
|
976 if (max - l == 0.0) |
|
977 { |
|
978 tmp[0] = a; |
|
979 tmp[1] = a; |
|
980 tmp[2] = a; |
|
981 } |
|
982 else |
|
983 { |
|
984 tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l); |
|
985 tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l); |
|
986 tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l); |
|
987 } |
|
988 } |
|
989 |
|
990 dest[0] = tmp[0] * MASK + 0.5; |
|
991 dest[1] = tmp[1] * MASK + 0.5; |
|
992 dest[2] = tmp[2] * MASK + 0.5; |
|
993 } |
|
994 |
|
995 static void |
|
996 set_sat (comp4_t dest[3], comp4_t src[3], comp4_t sat) |
|
997 { |
|
998 int id[3]; |
|
999 comp4_t min, max; |
|
1000 |
|
1001 if (src[0] > src[1]) |
|
1002 { |
|
1003 if (src[0] > src[2]) |
|
1004 { |
|
1005 id[0] = 0; |
|
1006 if (src[1] > src[2]) |
|
1007 { |
|
1008 id[1] = 1; |
|
1009 id[2] = 2; |
|
1010 } |
|
1011 else |
|
1012 { |
|
1013 id[1] = 2; |
|
1014 id[2] = 1; |
|
1015 } |
|
1016 } |
|
1017 else |
|
1018 { |
|
1019 id[0] = 2; |
|
1020 id[1] = 0; |
|
1021 id[2] = 1; |
|
1022 } |
|
1023 } |
|
1024 else |
|
1025 { |
|
1026 if (src[0] > src[2]) |
|
1027 { |
|
1028 id[0] = 1; |
|
1029 id[1] = 0; |
|
1030 id[2] = 2; |
|
1031 } |
|
1032 else |
|
1033 { |
|
1034 id[2] = 0; |
|
1035 if (src[1] > src[2]) |
|
1036 { |
|
1037 id[0] = 1; |
|
1038 id[1] = 2; |
|
1039 } |
|
1040 else |
|
1041 { |
|
1042 id[0] = 2; |
|
1043 id[1] = 1; |
|
1044 } |
|
1045 } |
|
1046 } |
|
1047 |
|
1048 max = dest[id[0]]; |
|
1049 min = dest[id[2]]; |
|
1050 if (max > min) |
|
1051 { |
|
1052 dest[id[1]] = (dest[id[1]] - min) * sat / (max - min); |
|
1053 dest[id[0]] = sat; |
|
1054 dest[id[2]] = 0; |
|
1055 } |
|
1056 else |
|
1057 { |
|
1058 dest[0] = dest[1] = dest[2] = 0; |
|
1059 } |
|
1060 } |
|
1061 |
|
1062 /* |
|
1063 * Hue: |
|
1064 * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb)) |
|
1065 */ |
|
1066 static inline void |
|
1067 blend_hsl_hue (comp4_t c[3], |
|
1068 comp4_t dc[3], |
|
1069 comp4_t da, |
|
1070 comp4_t sc[3], |
|
1071 comp4_t sa) |
|
1072 { |
|
1073 c[0] = sc[0] * da; |
|
1074 c[1] = sc[1] * da; |
|
1075 c[2] = sc[2] * da; |
|
1076 set_sat (c, c, SAT (dc) * sa); |
|
1077 set_lum (c, c, sa * da, LUM (dc) * sa); |
|
1078 } |
|
1079 |
|
1080 PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue) |
|
1081 |
|
1082 /* |
|
1083 * Saturation: |
|
1084 * B(Cb, Cs) = set_lum (set_sat (Cb, SAT (Cs)), LUM (Cb)) |
|
1085 */ |
|
1086 static inline void |
|
1087 blend_hsl_saturation (comp4_t c[3], |
|
1088 comp4_t dc[3], |
|
1089 comp4_t da, |
|
1090 comp4_t sc[3], |
|
1091 comp4_t sa) |
|
1092 { |
|
1093 c[0] = dc[0] * sa; |
|
1094 c[1] = dc[1] * sa; |
|
1095 c[2] = dc[2] * sa; |
|
1096 set_sat (c, c, SAT (sc) * da); |
|
1097 set_lum (c, c, sa * da, LUM (dc) * sa); |
|
1098 } |
|
1099 |
|
1100 PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation) |
|
1101 |
|
1102 /* |
|
1103 * Color: |
|
1104 * B(Cb, Cs) = set_lum (Cs, LUM (Cb)) |
|
1105 */ |
|
1106 static inline void |
|
1107 blend_hsl_color (comp4_t c[3], |
|
1108 comp4_t dc[3], |
|
1109 comp4_t da, |
|
1110 comp4_t sc[3], |
|
1111 comp4_t sa) |
|
1112 { |
|
1113 c[0] = sc[0] * da; |
|
1114 c[1] = sc[1] * da; |
|
1115 c[2] = sc[2] * da; |
|
1116 set_lum (c, c, sa * da, LUM (dc) * sa); |
|
1117 } |
|
1118 |
|
1119 PDF_NON_SEPARABLE_BLEND_MODE (hsl_color) |
|
1120 |
|
1121 /* |
|
1122 * Luminosity: |
|
1123 * B(Cb, Cs) = set_lum (Cb, LUM (Cs)) |
|
1124 */ |
|
1125 static inline void |
|
1126 blend_hsl_luminosity (comp4_t c[3], |
|
1127 comp4_t dc[3], |
|
1128 comp4_t da, |
|
1129 comp4_t sc[3], |
|
1130 comp4_t sa) |
|
1131 { |
|
1132 c[0] = dc[0] * sa; |
|
1133 c[1] = dc[1] * sa; |
|
1134 c[2] = dc[2] * sa; |
|
1135 set_lum (c, c, sa * da, LUM (sc) * da); |
|
1136 } |
|
1137 |
|
1138 PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity) |
|
1139 |
|
1140 #undef SAT |
|
1141 #undef LUM |
|
1142 #undef CH_MAX |
|
1143 #undef CH_MIN |
|
1144 #undef PDF_NON_SEPARABLE_BLEND_MODE |
|
1145 |
|
1146 /* All of the disjoint/conjoint composing functions |
|
1147 * |
|
1148 * The four entries in the first column indicate what source contributions |
|
1149 * come from each of the four areas of the picture -- areas covered by neither |
|
1150 * A nor B, areas covered only by A, areas covered only by B and finally |
|
1151 * areas covered by both A and B. |
|
1152 * |
|
1153 * Disjoint Conjoint |
|
1154 * Fa Fb Fa Fb |
|
1155 * (0,0,0,0) 0 0 0 0 |
|
1156 * (0,A,0,A) 1 0 1 0 |
|
1157 * (0,0,B,B) 0 1 0 1 |
|
1158 * (0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0) |
|
1159 * (0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1 |
|
1160 * (0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0 |
|
1161 * (0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1) |
|
1162 * (0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0 |
|
1163 * (0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0) |
|
1164 * (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0) |
|
1165 * (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b) |
|
1166 * (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0) |
|
1167 * |
|
1168 * See http://marc.info/?l=xfree-render&m=99792000027857&w=2 for more |
|
1169 * information about these operators. |
|
1170 */ |
|
1171 |
|
1172 #define COMBINE_A_OUT 1 |
|
1173 #define COMBINE_A_IN 2 |
|
1174 #define COMBINE_B_OUT 4 |
|
1175 #define COMBINE_B_IN 8 |
|
1176 |
|
1177 #define COMBINE_CLEAR 0 |
|
1178 #define COMBINE_A (COMBINE_A_OUT | COMBINE_A_IN) |
|
1179 #define COMBINE_B (COMBINE_B_OUT | COMBINE_B_IN) |
|
1180 #define COMBINE_A_OVER (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_A_IN) |
|
1181 #define COMBINE_B_OVER (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_B_IN) |
|
1182 #define COMBINE_A_ATOP (COMBINE_B_OUT | COMBINE_A_IN) |
|
1183 #define COMBINE_B_ATOP (COMBINE_A_OUT | COMBINE_B_IN) |
|
1184 #define COMBINE_XOR (COMBINE_A_OUT | COMBINE_B_OUT) |
|
1185 |
|
1186 /* portion covered by a but not b */ |
|
1187 static comp1_t |
|
1188 combine_disjoint_out_part (comp1_t a, comp1_t b) |
|
1189 { |
|
1190 /* min (1, (1-b) / a) */ |
|
1191 |
|
1192 b = ~b; /* 1 - b */ |
|
1193 if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ |
|
1194 return MASK; /* 1 */ |
|
1195 return DIV_UNc (b, a); /* (1-b) / a */ |
|
1196 } |
|
1197 |
|
1198 /* portion covered by both a and b */ |
|
1199 static comp1_t |
|
1200 combine_disjoint_in_part (comp1_t a, comp1_t b) |
|
1201 { |
|
1202 /* max (1-(1-b)/a,0) */ |
|
1203 /* = - min ((1-b)/a - 1, 0) */ |
|
1204 /* = 1 - min (1, (1-b)/a) */ |
|
1205 |
|
1206 b = ~b; /* 1 - b */ |
|
1207 if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ |
|
1208 return 0; /* 1 - 1 */ |
|
1209 return ~DIV_UNc(b, a); /* 1 - (1-b) / a */ |
|
1210 } |
|
1211 |
|
1212 /* portion covered by a but not b */ |
|
1213 static comp1_t |
|
1214 combine_conjoint_out_part (comp1_t a, comp1_t b) |
|
1215 { |
|
1216 /* max (1-b/a,0) */ |
|
1217 /* = 1-min(b/a,1) */ |
|
1218 |
|
1219 /* min (1, (1-b) / a) */ |
|
1220 |
|
1221 if (b >= a) /* b >= a -> b/a >= 1 */ |
|
1222 return 0x00; /* 0 */ |
|
1223 return ~DIV_UNc(b, a); /* 1 - b/a */ |
|
1224 } |
|
1225 |
|
1226 /* portion covered by both a and b */ |
|
1227 static comp1_t |
|
1228 combine_conjoint_in_part (comp1_t a, comp1_t b) |
|
1229 { |
|
1230 /* min (1,b/a) */ |
|
1231 |
|
1232 if (b >= a) /* b >= a -> b/a >= 1 */ |
|
1233 return MASK; /* 1 */ |
|
1234 return DIV_UNc (b, a); /* b/a */ |
|
1235 } |
|
1236 |
|
1237 #define GET_COMP(v, i) ((comp2_t) (comp1_t) ((v) >> i)) |
|
1238 |
|
1239 #define ADD(x, y, i, t) \ |
|
1240 ((t) = GET_COMP (x, i) + GET_COMP (y, i), \ |
|
1241 (comp4_t) ((comp1_t) ((t) | (0 - ((t) >> G_SHIFT)))) << (i)) |
|
1242 |
|
1243 #define GENERIC(x, y, i, ax, ay, t, u, v) \ |
|
1244 ((t) = (MUL_UNc (GET_COMP (y, i), ay, (u)) + \ |
|
1245 MUL_UNc (GET_COMP (x, i), ax, (v))), \ |
|
1246 (comp4_t) ((comp1_t) ((t) | \ |
|
1247 (0 - ((t) >> G_SHIFT)))) << (i)) |
|
1248 |
|
1249 static void |
|
1250 combine_disjoint_general_u (comp4_t * dest, |
|
1251 const comp4_t *src, |
|
1252 const comp4_t *mask, |
|
1253 int width, |
|
1254 comp1_t combine) |
|
1255 { |
|
1256 int i; |
|
1257 |
|
1258 for (i = 0; i < width; ++i) |
|
1259 { |
|
1260 comp4_t s = combine_mask (src, mask, i); |
|
1261 comp4_t d = *(dest + i); |
|
1262 comp4_t m, n, o, p; |
|
1263 comp2_t Fa, Fb, t, u, v; |
|
1264 comp1_t sa = s >> A_SHIFT; |
|
1265 comp1_t da = d >> A_SHIFT; |
|
1266 |
|
1267 switch (combine & COMBINE_A) |
|
1268 { |
|
1269 default: |
|
1270 Fa = 0; |
|
1271 break; |
|
1272 |
|
1273 case COMBINE_A_OUT: |
|
1274 Fa = combine_disjoint_out_part (sa, da); |
|
1275 break; |
|
1276 |
|
1277 case COMBINE_A_IN: |
|
1278 Fa = combine_disjoint_in_part (sa, da); |
|
1279 break; |
|
1280 |
|
1281 case COMBINE_A: |
|
1282 Fa = MASK; |
|
1283 break; |
|
1284 } |
|
1285 |
|
1286 switch (combine & COMBINE_B) |
|
1287 { |
|
1288 default: |
|
1289 Fb = 0; |
|
1290 break; |
|
1291 |
|
1292 case COMBINE_B_OUT: |
|
1293 Fb = combine_disjoint_out_part (da, sa); |
|
1294 break; |
|
1295 |
|
1296 case COMBINE_B_IN: |
|
1297 Fb = combine_disjoint_in_part (da, sa); |
|
1298 break; |
|
1299 |
|
1300 case COMBINE_B: |
|
1301 Fb = MASK; |
|
1302 break; |
|
1303 } |
|
1304 m = GENERIC (s, d, 0, Fa, Fb, t, u, v); |
|
1305 n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v); |
|
1306 o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v); |
|
1307 p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v); |
|
1308 s = m | n | o | p; |
|
1309 *(dest + i) = s; |
|
1310 } |
|
1311 } |
|
1312 |
|
1313 static void |
|
1314 combine_disjoint_over_u (pixman_implementation_t *imp, |
|
1315 pixman_op_t op, |
|
1316 comp4_t * dest, |
|
1317 const comp4_t * src, |
|
1318 const comp4_t * mask, |
|
1319 int width) |
|
1320 { |
|
1321 int i; |
|
1322 |
|
1323 for (i = 0; i < width; ++i) |
|
1324 { |
|
1325 comp4_t s = combine_mask (src, mask, i); |
|
1326 comp2_t a = s >> A_SHIFT; |
|
1327 |
|
1328 if (s != 0x00) |
|
1329 { |
|
1330 comp4_t d = *(dest + i); |
|
1331 a = combine_disjoint_out_part (d >> A_SHIFT, a); |
|
1332 UNcx4_MUL_UNc_ADD_UNcx4 (d, a, s); |
|
1333 |
|
1334 *(dest + i) = d; |
|
1335 } |
|
1336 } |
|
1337 } |
|
1338 |
|
1339 static void |
|
1340 combine_disjoint_in_u (pixman_implementation_t *imp, |
|
1341 pixman_op_t op, |
|
1342 comp4_t * dest, |
|
1343 const comp4_t * src, |
|
1344 const comp4_t * mask, |
|
1345 int width) |
|
1346 { |
|
1347 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN); |
|
1348 } |
|
1349 |
|
1350 static void |
|
1351 combine_disjoint_in_reverse_u (pixman_implementation_t *imp, |
|
1352 pixman_op_t op, |
|
1353 comp4_t * dest, |
|
1354 const comp4_t * src, |
|
1355 const comp4_t * mask, |
|
1356 int width) |
|
1357 { |
|
1358 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN); |
|
1359 } |
|
1360 |
|
1361 static void |
|
1362 combine_disjoint_out_u (pixman_implementation_t *imp, |
|
1363 pixman_op_t op, |
|
1364 comp4_t * dest, |
|
1365 const comp4_t * src, |
|
1366 const comp4_t * mask, |
|
1367 int width) |
|
1368 { |
|
1369 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT); |
|
1370 } |
|
1371 |
|
1372 static void |
|
1373 combine_disjoint_out_reverse_u (pixman_implementation_t *imp, |
|
1374 pixman_op_t op, |
|
1375 comp4_t * dest, |
|
1376 const comp4_t * src, |
|
1377 const comp4_t * mask, |
|
1378 int width) |
|
1379 { |
|
1380 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT); |
|
1381 } |
|
1382 |
|
1383 static void |
|
1384 combine_disjoint_atop_u (pixman_implementation_t *imp, |
|
1385 pixman_op_t op, |
|
1386 comp4_t * dest, |
|
1387 const comp4_t * src, |
|
1388 const comp4_t * mask, |
|
1389 int width) |
|
1390 { |
|
1391 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP); |
|
1392 } |
|
1393 |
|
1394 static void |
|
1395 combine_disjoint_atop_reverse_u (pixman_implementation_t *imp, |
|
1396 pixman_op_t op, |
|
1397 comp4_t * dest, |
|
1398 const comp4_t * src, |
|
1399 const comp4_t * mask, |
|
1400 int width) |
|
1401 { |
|
1402 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP); |
|
1403 } |
|
1404 |
|
1405 static void |
|
1406 combine_disjoint_xor_u (pixman_implementation_t *imp, |
|
1407 pixman_op_t op, |
|
1408 comp4_t * dest, |
|
1409 const comp4_t * src, |
|
1410 const comp4_t * mask, |
|
1411 int width) |
|
1412 { |
|
1413 combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR); |
|
1414 } |
|
1415 |
|
1416 static void |
|
1417 combine_conjoint_general_u (comp4_t * dest, |
|
1418 const comp4_t *src, |
|
1419 const comp4_t *mask, |
|
1420 int width, |
|
1421 comp1_t combine) |
|
1422 { |
|
1423 int i; |
|
1424 |
|
1425 for (i = 0; i < width; ++i) |
|
1426 { |
|
1427 comp4_t s = combine_mask (src, mask, i); |
|
1428 comp4_t d = *(dest + i); |
|
1429 comp4_t m, n, o, p; |
|
1430 comp2_t Fa, Fb, t, u, v; |
|
1431 comp1_t sa = s >> A_SHIFT; |
|
1432 comp1_t da = d >> A_SHIFT; |
|
1433 |
|
1434 switch (combine & COMBINE_A) |
|
1435 { |
|
1436 default: |
|
1437 Fa = 0; |
|
1438 break; |
|
1439 |
|
1440 case COMBINE_A_OUT: |
|
1441 Fa = combine_conjoint_out_part (sa, da); |
|
1442 break; |
|
1443 |
|
1444 case COMBINE_A_IN: |
|
1445 Fa = combine_conjoint_in_part (sa, da); |
|
1446 break; |
|
1447 |
|
1448 case COMBINE_A: |
|
1449 Fa = MASK; |
|
1450 break; |
|
1451 } |
|
1452 |
|
1453 switch (combine & COMBINE_B) |
|
1454 { |
|
1455 default: |
|
1456 Fb = 0; |
|
1457 break; |
|
1458 |
|
1459 case COMBINE_B_OUT: |
|
1460 Fb = combine_conjoint_out_part (da, sa); |
|
1461 break; |
|
1462 |
|
1463 case COMBINE_B_IN: |
|
1464 Fb = combine_conjoint_in_part (da, sa); |
|
1465 break; |
|
1466 |
|
1467 case COMBINE_B: |
|
1468 Fb = MASK; |
|
1469 break; |
|
1470 } |
|
1471 |
|
1472 m = GENERIC (s, d, 0, Fa, Fb, t, u, v); |
|
1473 n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v); |
|
1474 o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v); |
|
1475 p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v); |
|
1476 |
|
1477 s = m | n | o | p; |
|
1478 |
|
1479 *(dest + i) = s; |
|
1480 } |
|
1481 } |
|
1482 |
|
1483 static void |
|
1484 combine_conjoint_over_u (pixman_implementation_t *imp, |
|
1485 pixman_op_t op, |
|
1486 comp4_t * dest, |
|
1487 const comp4_t * src, |
|
1488 const comp4_t * mask, |
|
1489 int width) |
|
1490 { |
|
1491 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER); |
|
1492 } |
|
1493 |
|
1494 static void |
|
1495 combine_conjoint_over_reverse_u (pixman_implementation_t *imp, |
|
1496 pixman_op_t op, |
|
1497 comp4_t * dest, |
|
1498 const comp4_t * src, |
|
1499 const comp4_t * mask, |
|
1500 int width) |
|
1501 { |
|
1502 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER); |
|
1503 } |
|
1504 |
|
1505 static void |
|
1506 combine_conjoint_in_u (pixman_implementation_t *imp, |
|
1507 pixman_op_t op, |
|
1508 comp4_t * dest, |
|
1509 const comp4_t * src, |
|
1510 const comp4_t * mask, |
|
1511 int width) |
|
1512 { |
|
1513 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN); |
|
1514 } |
|
1515 |
|
1516 static void |
|
1517 combine_conjoint_in_reverse_u (pixman_implementation_t *imp, |
|
1518 pixman_op_t op, |
|
1519 comp4_t * dest, |
|
1520 const comp4_t * src, |
|
1521 const comp4_t * mask, |
|
1522 int width) |
|
1523 { |
|
1524 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN); |
|
1525 } |
|
1526 |
|
1527 static void |
|
1528 combine_conjoint_out_u (pixman_implementation_t *imp, |
|
1529 pixman_op_t op, |
|
1530 comp4_t * dest, |
|
1531 const comp4_t * src, |
|
1532 const comp4_t * mask, |
|
1533 int width) |
|
1534 { |
|
1535 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT); |
|
1536 } |
|
1537 |
|
1538 static void |
|
1539 combine_conjoint_out_reverse_u (pixman_implementation_t *imp, |
|
1540 pixman_op_t op, |
|
1541 comp4_t * dest, |
|
1542 const comp4_t * src, |
|
1543 const comp4_t * mask, |
|
1544 int width) |
|
1545 { |
|
1546 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT); |
|
1547 } |
|
1548 |
|
1549 static void |
|
1550 combine_conjoint_atop_u (pixman_implementation_t *imp, |
|
1551 pixman_op_t op, |
|
1552 comp4_t * dest, |
|
1553 const comp4_t * src, |
|
1554 const comp4_t * mask, |
|
1555 int width) |
|
1556 { |
|
1557 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP); |
|
1558 } |
|
1559 |
|
1560 static void |
|
1561 combine_conjoint_atop_reverse_u (pixman_implementation_t *imp, |
|
1562 pixman_op_t op, |
|
1563 comp4_t * dest, |
|
1564 const comp4_t * src, |
|
1565 const comp4_t * mask, |
|
1566 int width) |
|
1567 { |
|
1568 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP); |
|
1569 } |
|
1570 |
|
1571 static void |
|
1572 combine_conjoint_xor_u (pixman_implementation_t *imp, |
|
1573 pixman_op_t op, |
|
1574 comp4_t * dest, |
|
1575 const comp4_t * src, |
|
1576 const comp4_t * mask, |
|
1577 int width) |
|
1578 { |
|
1579 combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR); |
|
1580 } |
|
1581 |
|
1582 /************************************************************************/ |
|
1583 /*********************** Per Channel functions **************************/ |
|
1584 /************************************************************************/ |
|
1585 |
|
1586 static void |
|
1587 combine_clear_ca (pixman_implementation_t *imp, |
|
1588 pixman_op_t op, |
|
1589 comp4_t * dest, |
|
1590 const comp4_t * src, |
|
1591 const comp4_t * mask, |
|
1592 int width) |
|
1593 { |
|
1594 memset (dest, 0, width * sizeof(comp4_t)); |
|
1595 } |
|
1596 |
|
1597 static void |
|
1598 combine_src_ca (pixman_implementation_t *imp, |
|
1599 pixman_op_t op, |
|
1600 comp4_t * dest, |
|
1601 const comp4_t * src, |
|
1602 const comp4_t * mask, |
|
1603 int width) |
|
1604 { |
|
1605 int i; |
|
1606 |
|
1607 for (i = 0; i < width; ++i) |
|
1608 { |
|
1609 comp4_t s = *(src + i); |
|
1610 comp4_t m = *(mask + i); |
|
1611 |
|
1612 combine_mask_value_ca (&s, &m); |
|
1613 |
|
1614 *(dest + i) = s; |
|
1615 } |
|
1616 } |
|
1617 |
|
1618 static void |
|
1619 combine_over_ca (pixman_implementation_t *imp, |
|
1620 pixman_op_t op, |
|
1621 comp4_t * dest, |
|
1622 const comp4_t * src, |
|
1623 const comp4_t * mask, |
|
1624 int width) |
|
1625 { |
|
1626 int i; |
|
1627 |
|
1628 for (i = 0; i < width; ++i) |
|
1629 { |
|
1630 comp4_t s = *(src + i); |
|
1631 comp4_t m = *(mask + i); |
|
1632 comp4_t a; |
|
1633 |
|
1634 combine_mask_ca (&s, &m); |
|
1635 |
|
1636 a = ~m; |
|
1637 if (a) |
|
1638 { |
|
1639 comp4_t d = *(dest + i); |
|
1640 UNcx4_MUL_UNcx4_ADD_UNcx4 (d, a, s); |
|
1641 s = d; |
|
1642 } |
|
1643 |
|
1644 *(dest + i) = s; |
|
1645 } |
|
1646 } |
|
1647 |
|
1648 static void |
|
1649 combine_over_reverse_ca (pixman_implementation_t *imp, |
|
1650 pixman_op_t op, |
|
1651 comp4_t * dest, |
|
1652 const comp4_t * src, |
|
1653 const comp4_t * mask, |
|
1654 int width) |
|
1655 { |
|
1656 int i; |
|
1657 |
|
1658 for (i = 0; i < width; ++i) |
|
1659 { |
|
1660 comp4_t d = *(dest + i); |
|
1661 comp4_t a = ~d >> A_SHIFT; |
|
1662 |
|
1663 if (a) |
|
1664 { |
|
1665 comp4_t s = *(src + i); |
|
1666 comp4_t m = *(mask + i); |
|
1667 |
|
1668 UNcx4_MUL_UNcx4 (s, m); |
|
1669 UNcx4_MUL_UNc_ADD_UNcx4 (s, a, d); |
|
1670 |
|
1671 *(dest + i) = s; |
|
1672 } |
|
1673 } |
|
1674 } |
|
1675 |
|
1676 static void |
|
1677 combine_in_ca (pixman_implementation_t *imp, |
|
1678 pixman_op_t op, |
|
1679 comp4_t * dest, |
|
1680 const comp4_t * src, |
|
1681 const comp4_t * mask, |
|
1682 int width) |
|
1683 { |
|
1684 int i; |
|
1685 |
|
1686 for (i = 0; i < width; ++i) |
|
1687 { |
|
1688 comp4_t d = *(dest + i); |
|
1689 comp2_t a = d >> A_SHIFT; |
|
1690 comp4_t s = 0; |
|
1691 |
|
1692 if (a) |
|
1693 { |
|
1694 comp4_t m = *(mask + i); |
|
1695 |
|
1696 s = *(src + i); |
|
1697 combine_mask_value_ca (&s, &m); |
|
1698 |
|
1699 if (a != MASK) |
|
1700 UNcx4_MUL_UNc (s, a); |
|
1701 } |
|
1702 |
|
1703 *(dest + i) = s; |
|
1704 } |
|
1705 } |
|
1706 |
|
1707 static void |
|
1708 combine_in_reverse_ca (pixman_implementation_t *imp, |
|
1709 pixman_op_t op, |
|
1710 comp4_t * dest, |
|
1711 const comp4_t * src, |
|
1712 const comp4_t * mask, |
|
1713 int width) |
|
1714 { |
|
1715 int i; |
|
1716 |
|
1717 for (i = 0; i < width; ++i) |
|
1718 { |
|
1719 comp4_t s = *(src + i); |
|
1720 comp4_t m = *(mask + i); |
|
1721 comp4_t a; |
|
1722 |
|
1723 combine_mask_alpha_ca (&s, &m); |
|
1724 |
|
1725 a = m; |
|
1726 if (a != ~0) |
|
1727 { |
|
1728 comp4_t d = 0; |
|
1729 |
|
1730 if (a) |
|
1731 { |
|
1732 d = *(dest + i); |
|
1733 UNcx4_MUL_UNcx4 (d, a); |
|
1734 } |
|
1735 |
|
1736 *(dest + i) = d; |
|
1737 } |
|
1738 } |
|
1739 } |
|
1740 |
|
1741 static void |
|
1742 combine_out_ca (pixman_implementation_t *imp, |
|
1743 pixman_op_t op, |
|
1744 comp4_t * dest, |
|
1745 const comp4_t * src, |
|
1746 const comp4_t * mask, |
|
1747 int width) |
|
1748 { |
|
1749 int i; |
|
1750 |
|
1751 for (i = 0; i < width; ++i) |
|
1752 { |
|
1753 comp4_t d = *(dest + i); |
|
1754 comp2_t a = ~d >> A_SHIFT; |
|
1755 comp4_t s = 0; |
|
1756 |
|
1757 if (a) |
|
1758 { |
|
1759 comp4_t m = *(mask + i); |
|
1760 |
|
1761 s = *(src + i); |
|
1762 combine_mask_value_ca (&s, &m); |
|
1763 |
|
1764 if (a != MASK) |
|
1765 UNcx4_MUL_UNc (s, a); |
|
1766 } |
|
1767 |
|
1768 *(dest + i) = s; |
|
1769 } |
|
1770 } |
|
1771 |
|
1772 static void |
|
1773 combine_out_reverse_ca (pixman_implementation_t *imp, |
|
1774 pixman_op_t op, |
|
1775 comp4_t * dest, |
|
1776 const comp4_t * src, |
|
1777 const comp4_t * mask, |
|
1778 int width) |
|
1779 { |
|
1780 int i; |
|
1781 |
|
1782 for (i = 0; i < width; ++i) |
|
1783 { |
|
1784 comp4_t s = *(src + i); |
|
1785 comp4_t m = *(mask + i); |
|
1786 comp4_t a; |
|
1787 |
|
1788 combine_mask_alpha_ca (&s, &m); |
|
1789 |
|
1790 a = ~m; |
|
1791 if (a != ~0) |
|
1792 { |
|
1793 comp4_t d = 0; |
|
1794 |
|
1795 if (a) |
|
1796 { |
|
1797 d = *(dest + i); |
|
1798 UNcx4_MUL_UNcx4 (d, a); |
|
1799 } |
|
1800 |
|
1801 *(dest + i) = d; |
|
1802 } |
|
1803 } |
|
1804 } |
|
1805 |
|
1806 static void |
|
1807 combine_atop_ca (pixman_implementation_t *imp, |
|
1808 pixman_op_t op, |
|
1809 comp4_t * dest, |
|
1810 const comp4_t * src, |
|
1811 const comp4_t * mask, |
|
1812 int width) |
|
1813 { |
|
1814 int i; |
|
1815 |
|
1816 for (i = 0; i < width; ++i) |
|
1817 { |
|
1818 comp4_t d = *(dest + i); |
|
1819 comp4_t s = *(src + i); |
|
1820 comp4_t m = *(mask + i); |
|
1821 comp4_t ad; |
|
1822 comp2_t as = d >> A_SHIFT; |
|
1823 |
|
1824 combine_mask_ca (&s, &m); |
|
1825 |
|
1826 ad = ~m; |
|
1827 |
|
1828 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (d, ad, s, as); |
|
1829 |
|
1830 *(dest + i) = d; |
|
1831 } |
|
1832 } |
|
1833 |
|
1834 static void |
|
1835 combine_atop_reverse_ca (pixman_implementation_t *imp, |
|
1836 pixman_op_t op, |
|
1837 comp4_t * dest, |
|
1838 const comp4_t * src, |
|
1839 const comp4_t * mask, |
|
1840 int width) |
|
1841 { |
|
1842 int i; |
|
1843 |
|
1844 for (i = 0; i < width; ++i) |
|
1845 { |
|
1846 comp4_t d = *(dest + i); |
|
1847 comp4_t s = *(src + i); |
|
1848 comp4_t m = *(mask + i); |
|
1849 comp4_t ad; |
|
1850 comp2_t as = ~d >> A_SHIFT; |
|
1851 |
|
1852 combine_mask_ca (&s, &m); |
|
1853 |
|
1854 ad = m; |
|
1855 |
|
1856 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (d, ad, s, as); |
|
1857 |
|
1858 *(dest + i) = d; |
|
1859 } |
|
1860 } |
|
1861 |
|
1862 static void |
|
1863 combine_xor_ca (pixman_implementation_t *imp, |
|
1864 pixman_op_t op, |
|
1865 comp4_t * dest, |
|
1866 const comp4_t * src, |
|
1867 const comp4_t * mask, |
|
1868 int width) |
|
1869 { |
|
1870 int i; |
|
1871 |
|
1872 for (i = 0; i < width; ++i) |
|
1873 { |
|
1874 comp4_t d = *(dest + i); |
|
1875 comp4_t s = *(src + i); |
|
1876 comp4_t m = *(mask + i); |
|
1877 comp4_t ad; |
|
1878 comp2_t as = ~d >> A_SHIFT; |
|
1879 |
|
1880 combine_mask_ca (&s, &m); |
|
1881 |
|
1882 ad = ~m; |
|
1883 |
|
1884 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (d, ad, s, as); |
|
1885 |
|
1886 *(dest + i) = d; |
|
1887 } |
|
1888 } |
|
1889 |
|
1890 static void |
|
1891 combine_add_ca (pixman_implementation_t *imp, |
|
1892 pixman_op_t op, |
|
1893 comp4_t * dest, |
|
1894 const comp4_t * src, |
|
1895 const comp4_t * mask, |
|
1896 int width) |
|
1897 { |
|
1898 int i; |
|
1899 |
|
1900 for (i = 0; i < width; ++i) |
|
1901 { |
|
1902 comp4_t s = *(src + i); |
|
1903 comp4_t m = *(mask + i); |
|
1904 comp4_t d = *(dest + i); |
|
1905 |
|
1906 combine_mask_value_ca (&s, &m); |
|
1907 |
|
1908 UNcx4_ADD_UNcx4 (d, s); |
|
1909 |
|
1910 *(dest + i) = d; |
|
1911 } |
|
1912 } |
|
1913 |
|
1914 static void |
|
1915 combine_saturate_ca (pixman_implementation_t *imp, |
|
1916 pixman_op_t op, |
|
1917 comp4_t * dest, |
|
1918 const comp4_t * src, |
|
1919 const comp4_t * mask, |
|
1920 int width) |
|
1921 { |
|
1922 int i; |
|
1923 |
|
1924 for (i = 0; i < width; ++i) |
|
1925 { |
|
1926 comp4_t s, d; |
|
1927 comp2_t sa, sr, sg, sb, da; |
|
1928 comp2_t t, u, v; |
|
1929 comp4_t m, n, o, p; |
|
1930 |
|
1931 d = *(dest + i); |
|
1932 s = *(src + i); |
|
1933 m = *(mask + i); |
|
1934 |
|
1935 combine_mask_ca (&s, &m); |
|
1936 |
|
1937 sa = (m >> A_SHIFT); |
|
1938 sr = (m >> R_SHIFT) & MASK; |
|
1939 sg = (m >> G_SHIFT) & MASK; |
|
1940 sb = m & MASK; |
|
1941 da = ~d >> A_SHIFT; |
|
1942 |
|
1943 if (sb <= da) |
|
1944 m = ADD (s, d, 0, t); |
|
1945 else |
|
1946 m = GENERIC (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v); |
|
1947 |
|
1948 if (sg <= da) |
|
1949 n = ADD (s, d, G_SHIFT, t); |
|
1950 else |
|
1951 n = GENERIC (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v); |
|
1952 |
|
1953 if (sr <= da) |
|
1954 o = ADD (s, d, R_SHIFT, t); |
|
1955 else |
|
1956 o = GENERIC (s, d, R_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v); |
|
1957 |
|
1958 if (sa <= da) |
|
1959 p = ADD (s, d, A_SHIFT, t); |
|
1960 else |
|
1961 p = GENERIC (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v); |
|
1962 |
|
1963 *(dest + i) = m | n | o | p; |
|
1964 } |
|
1965 } |
|
1966 |
|
1967 static void |
|
1968 combine_disjoint_general_ca (comp4_t * dest, |
|
1969 const comp4_t *src, |
|
1970 const comp4_t *mask, |
|
1971 int width, |
|
1972 comp1_t combine) |
|
1973 { |
|
1974 int i; |
|
1975 |
|
1976 for (i = 0; i < width; ++i) |
|
1977 { |
|
1978 comp4_t s, d; |
|
1979 comp4_t m, n, o, p; |
|
1980 comp4_t Fa, Fb; |
|
1981 comp2_t t, u, v; |
|
1982 comp4_t sa; |
|
1983 comp1_t da; |
|
1984 |
|
1985 s = *(src + i); |
|
1986 m = *(mask + i); |
|
1987 d = *(dest + i); |
|
1988 da = d >> A_SHIFT; |
|
1989 |
|
1990 combine_mask_ca (&s, &m); |
|
1991 |
|
1992 sa = m; |
|
1993 |
|
1994 switch (combine & COMBINE_A) |
|
1995 { |
|
1996 default: |
|
1997 Fa = 0; |
|
1998 break; |
|
1999 |
|
2000 case COMBINE_A_OUT: |
|
2001 m = (comp4_t)combine_disjoint_out_part ((comp1_t) (sa >> 0), da); |
|
2002 n = (comp4_t)combine_disjoint_out_part ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT; |
|
2003 o = (comp4_t)combine_disjoint_out_part ((comp1_t) (sa >> R_SHIFT), da) << R_SHIFT; |
|
2004 p = (comp4_t)combine_disjoint_out_part ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT; |
|
2005 Fa = m | n | o | p; |
|
2006 break; |
|
2007 |
|
2008 case COMBINE_A_IN: |
|
2009 m = (comp4_t)combine_disjoint_in_part ((comp1_t) (sa >> 0), da); |
|
2010 n = (comp4_t)combine_disjoint_in_part ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT; |
|
2011 o = (comp4_t)combine_disjoint_in_part ((comp1_t) (sa >> R_SHIFT), da) << R_SHIFT; |
|
2012 p = (comp4_t)combine_disjoint_in_part ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT; |
|
2013 Fa = m | n | o | p; |
|
2014 break; |
|
2015 |
|
2016 case COMBINE_A: |
|
2017 Fa = ~0; |
|
2018 break; |
|
2019 } |
|
2020 |
|
2021 switch (combine & COMBINE_B) |
|
2022 { |
|
2023 default: |
|
2024 Fb = 0; |
|
2025 break; |
|
2026 |
|
2027 case COMBINE_B_OUT: |
|
2028 m = (comp4_t)combine_disjoint_out_part (da, (comp1_t) (sa >> 0)); |
|
2029 n = (comp4_t)combine_disjoint_out_part (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT; |
|
2030 o = (comp4_t)combine_disjoint_out_part (da, (comp1_t) (sa >> R_SHIFT)) << R_SHIFT; |
|
2031 p = (comp4_t)combine_disjoint_out_part (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT; |
|
2032 Fb = m | n | o | p; |
|
2033 break; |
|
2034 |
|
2035 case COMBINE_B_IN: |
|
2036 m = (comp4_t)combine_disjoint_in_part (da, (comp1_t) (sa >> 0)); |
|
2037 n = (comp4_t)combine_disjoint_in_part (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT; |
|
2038 o = (comp4_t)combine_disjoint_in_part (da, (comp1_t) (sa >> R_SHIFT)) << R_SHIFT; |
|
2039 p = (comp4_t)combine_disjoint_in_part (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT; |
|
2040 Fb = m | n | o | p; |
|
2041 break; |
|
2042 |
|
2043 case COMBINE_B: |
|
2044 Fb = ~0; |
|
2045 break; |
|
2046 } |
|
2047 m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v); |
|
2048 n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v); |
|
2049 o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v); |
|
2050 p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v); |
|
2051 |
|
2052 s = m | n | o | p; |
|
2053 |
|
2054 *(dest + i) = s; |
|
2055 } |
|
2056 } |
|
2057 |
|
2058 static void |
|
2059 combine_disjoint_over_ca (pixman_implementation_t *imp, |
|
2060 pixman_op_t op, |
|
2061 comp4_t * dest, |
|
2062 const comp4_t * src, |
|
2063 const comp4_t * mask, |
|
2064 int width) |
|
2065 { |
|
2066 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER); |
|
2067 } |
|
2068 |
|
2069 static void |
|
2070 combine_disjoint_in_ca (pixman_implementation_t *imp, |
|
2071 pixman_op_t op, |
|
2072 comp4_t * dest, |
|
2073 const comp4_t * src, |
|
2074 const comp4_t * mask, |
|
2075 int width) |
|
2076 { |
|
2077 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN); |
|
2078 } |
|
2079 |
|
2080 static void |
|
2081 combine_disjoint_in_reverse_ca (pixman_implementation_t *imp, |
|
2082 pixman_op_t op, |
|
2083 comp4_t * dest, |
|
2084 const comp4_t * src, |
|
2085 const comp4_t * mask, |
|
2086 int width) |
|
2087 { |
|
2088 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN); |
|
2089 } |
|
2090 |
|
2091 static void |
|
2092 combine_disjoint_out_ca (pixman_implementation_t *imp, |
|
2093 pixman_op_t op, |
|
2094 comp4_t * dest, |
|
2095 const comp4_t * src, |
|
2096 const comp4_t * mask, |
|
2097 int width) |
|
2098 { |
|
2099 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT); |
|
2100 } |
|
2101 |
|
2102 static void |
|
2103 combine_disjoint_out_reverse_ca (pixman_implementation_t *imp, |
|
2104 pixman_op_t op, |
|
2105 comp4_t * dest, |
|
2106 const comp4_t * src, |
|
2107 const comp4_t * mask, |
|
2108 int width) |
|
2109 { |
|
2110 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT); |
|
2111 } |
|
2112 |
|
2113 static void |
|
2114 combine_disjoint_atop_ca (pixman_implementation_t *imp, |
|
2115 pixman_op_t op, |
|
2116 comp4_t * dest, |
|
2117 const comp4_t * src, |
|
2118 const comp4_t * mask, |
|
2119 int width) |
|
2120 { |
|
2121 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP); |
|
2122 } |
|
2123 |
|
2124 static void |
|
2125 combine_disjoint_atop_reverse_ca (pixman_implementation_t *imp, |
|
2126 pixman_op_t op, |
|
2127 comp4_t * dest, |
|
2128 const comp4_t * src, |
|
2129 const comp4_t * mask, |
|
2130 int width) |
|
2131 { |
|
2132 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP); |
|
2133 } |
|
2134 |
|
2135 static void |
|
2136 combine_disjoint_xor_ca (pixman_implementation_t *imp, |
|
2137 pixman_op_t op, |
|
2138 comp4_t * dest, |
|
2139 const comp4_t * src, |
|
2140 const comp4_t * mask, |
|
2141 int width) |
|
2142 { |
|
2143 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR); |
|
2144 } |
|
2145 |
|
2146 static void |
|
2147 combine_conjoint_general_ca (comp4_t * dest, |
|
2148 const comp4_t *src, |
|
2149 const comp4_t *mask, |
|
2150 int width, |
|
2151 comp1_t combine) |
|
2152 { |
|
2153 int i; |
|
2154 |
|
2155 for (i = 0; i < width; ++i) |
|
2156 { |
|
2157 comp4_t s, d; |
|
2158 comp4_t m, n, o, p; |
|
2159 comp4_t Fa, Fb; |
|
2160 comp2_t t, u, v; |
|
2161 comp4_t sa; |
|
2162 comp1_t da; |
|
2163 |
|
2164 s = *(src + i); |
|
2165 m = *(mask + i); |
|
2166 d = *(dest + i); |
|
2167 da = d >> A_SHIFT; |
|
2168 |
|
2169 combine_mask_ca (&s, &m); |
|
2170 |
|
2171 sa = m; |
|
2172 |
|
2173 switch (combine & COMBINE_A) |
|
2174 { |
|
2175 default: |
|
2176 Fa = 0; |
|
2177 break; |
|
2178 |
|
2179 case COMBINE_A_OUT: |
|
2180 m = (comp4_t)combine_conjoint_out_part ((comp1_t) (sa >> 0), da); |
|
2181 n = (comp4_t)combine_conjoint_out_part ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT; |
|
2182 o = (comp4_t)combine_conjoint_out_part ((comp1_t) (sa >> R_SHIFT), da) << R_SHIFT; |
|
2183 p = (comp4_t)combine_conjoint_out_part ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT; |
|
2184 Fa = m | n | o | p; |
|
2185 break; |
|
2186 |
|
2187 case COMBINE_A_IN: |
|
2188 m = (comp4_t)combine_conjoint_in_part ((comp1_t) (sa >> 0), da); |
|
2189 n = (comp4_t)combine_conjoint_in_part ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT; |
|
2190 o = (comp4_t)combine_conjoint_in_part ((comp1_t) (sa >> R_SHIFT), da) << R_SHIFT; |
|
2191 p = (comp4_t)combine_conjoint_in_part ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT; |
|
2192 Fa = m | n | o | p; |
|
2193 break; |
|
2194 |
|
2195 case COMBINE_A: |
|
2196 Fa = ~0; |
|
2197 break; |
|
2198 } |
|
2199 |
|
2200 switch (combine & COMBINE_B) |
|
2201 { |
|
2202 default: |
|
2203 Fb = 0; |
|
2204 break; |
|
2205 |
|
2206 case COMBINE_B_OUT: |
|
2207 m = (comp4_t)combine_conjoint_out_part (da, (comp1_t) (sa >> 0)); |
|
2208 n = (comp4_t)combine_conjoint_out_part (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT; |
|
2209 o = (comp4_t)combine_conjoint_out_part (da, (comp1_t) (sa >> R_SHIFT)) << R_SHIFT; |
|
2210 p = (comp4_t)combine_conjoint_out_part (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT; |
|
2211 Fb = m | n | o | p; |
|
2212 break; |
|
2213 |
|
2214 case COMBINE_B_IN: |
|
2215 m = (comp4_t)combine_conjoint_in_part (da, (comp1_t) (sa >> 0)); |
|
2216 n = (comp4_t)combine_conjoint_in_part (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT; |
|
2217 o = (comp4_t)combine_conjoint_in_part (da, (comp1_t) (sa >> R_SHIFT)) << R_SHIFT; |
|
2218 p = (comp4_t)combine_conjoint_in_part (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT; |
|
2219 Fb = m | n | o | p; |
|
2220 break; |
|
2221 |
|
2222 case COMBINE_B: |
|
2223 Fb = ~0; |
|
2224 break; |
|
2225 } |
|
2226 m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v); |
|
2227 n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v); |
|
2228 o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v); |
|
2229 p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v); |
|
2230 |
|
2231 s = m | n | o | p; |
|
2232 |
|
2233 *(dest + i) = s; |
|
2234 } |
|
2235 } |
|
2236 |
|
2237 static void |
|
2238 combine_conjoint_over_ca (pixman_implementation_t *imp, |
|
2239 pixman_op_t op, |
|
2240 comp4_t * dest, |
|
2241 const comp4_t * src, |
|
2242 const comp4_t * mask, |
|
2243 int width) |
|
2244 { |
|
2245 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER); |
|
2246 } |
|
2247 |
|
2248 static void |
|
2249 combine_conjoint_over_reverse_ca (pixman_implementation_t *imp, |
|
2250 pixman_op_t op, |
|
2251 comp4_t * dest, |
|
2252 const comp4_t * src, |
|
2253 const comp4_t * mask, |
|
2254 int width) |
|
2255 { |
|
2256 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER); |
|
2257 } |
|
2258 |
|
2259 static void |
|
2260 combine_conjoint_in_ca (pixman_implementation_t *imp, |
|
2261 pixman_op_t op, |
|
2262 comp4_t * dest, |
|
2263 const comp4_t * src, |
|
2264 const comp4_t * mask, |
|
2265 int width) |
|
2266 { |
|
2267 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN); |
|
2268 } |
|
2269 |
|
2270 static void |
|
2271 combine_conjoint_in_reverse_ca (pixman_implementation_t *imp, |
|
2272 pixman_op_t op, |
|
2273 comp4_t * dest, |
|
2274 const comp4_t * src, |
|
2275 const comp4_t * mask, |
|
2276 int width) |
|
2277 { |
|
2278 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN); |
|
2279 } |
|
2280 |
|
2281 static void |
|
2282 combine_conjoint_out_ca (pixman_implementation_t *imp, |
|
2283 pixman_op_t op, |
|
2284 comp4_t * dest, |
|
2285 const comp4_t * src, |
|
2286 const comp4_t * mask, |
|
2287 int width) |
|
2288 { |
|
2289 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT); |
|
2290 } |
|
2291 |
|
2292 static void |
|
2293 combine_conjoint_out_reverse_ca (pixman_implementation_t *imp, |
|
2294 pixman_op_t op, |
|
2295 comp4_t * dest, |
|
2296 const comp4_t * src, |
|
2297 const comp4_t * mask, |
|
2298 int width) |
|
2299 { |
|
2300 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT); |
|
2301 } |
|
2302 |
|
2303 static void |
|
2304 combine_conjoint_atop_ca (pixman_implementation_t *imp, |
|
2305 pixman_op_t op, |
|
2306 comp4_t * dest, |
|
2307 const comp4_t * src, |
|
2308 const comp4_t * mask, |
|
2309 int width) |
|
2310 { |
|
2311 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP); |
|
2312 } |
|
2313 |
|
2314 static void |
|
2315 combine_conjoint_atop_reverse_ca (pixman_implementation_t *imp, |
|
2316 pixman_op_t op, |
|
2317 comp4_t * dest, |
|
2318 const comp4_t * src, |
|
2319 const comp4_t * mask, |
|
2320 int width) |
|
2321 { |
|
2322 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP); |
|
2323 } |
|
2324 |
|
2325 static void |
|
2326 combine_conjoint_xor_ca (pixman_implementation_t *imp, |
|
2327 pixman_op_t op, |
|
2328 comp4_t * dest, |
|
2329 const comp4_t * src, |
|
2330 const comp4_t * mask, |
|
2331 int width) |
|
2332 { |
|
2333 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR); |
|
2334 } |
|
2335 |
|
2336 void |
|
2337 _pixman_setup_combiner_functions_width (pixman_implementation_t *imp) |
|
2338 { |
|
2339 /* Unified alpha */ |
|
2340 imp->combine_width[PIXMAN_OP_CLEAR] = combine_clear; |
|
2341 imp->combine_width[PIXMAN_OP_SRC] = combine_src_u; |
|
2342 imp->combine_width[PIXMAN_OP_DST] = combine_dst; |
|
2343 imp->combine_width[PIXMAN_OP_OVER] = combine_over_u; |
|
2344 imp->combine_width[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_u; |
|
2345 imp->combine_width[PIXMAN_OP_IN] = combine_in_u; |
|
2346 imp->combine_width[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_u; |
|
2347 imp->combine_width[PIXMAN_OP_OUT] = combine_out_u; |
|
2348 imp->combine_width[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_u; |
|
2349 imp->combine_width[PIXMAN_OP_ATOP] = combine_atop_u; |
|
2350 imp->combine_width[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u; |
|
2351 imp->combine_width[PIXMAN_OP_XOR] = combine_xor_u; |
|
2352 imp->combine_width[PIXMAN_OP_ADD] = combine_add_u; |
|
2353 imp->combine_width[PIXMAN_OP_SATURATE] = combine_saturate_u; |
|
2354 |
|
2355 /* Disjoint, unified */ |
|
2356 imp->combine_width[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear; |
|
2357 imp->combine_width[PIXMAN_OP_DISJOINT_SRC] = combine_src_u; |
|
2358 imp->combine_width[PIXMAN_OP_DISJOINT_DST] = combine_dst; |
|
2359 imp->combine_width[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u; |
|
2360 imp->combine_width[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_u; |
|
2361 imp->combine_width[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u; |
|
2362 imp->combine_width[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_u; |
|
2363 imp->combine_width[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_u; |
|
2364 imp->combine_width[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_u; |
|
2365 imp->combine_width[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_u; |
|
2366 imp->combine_width[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_u; |
|
2367 imp->combine_width[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_u; |
|
2368 |
|
2369 /* Conjoint, unified */ |
|
2370 imp->combine_width[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear; |
|
2371 imp->combine_width[PIXMAN_OP_CONJOINT_SRC] = combine_src_u; |
|
2372 imp->combine_width[PIXMAN_OP_CONJOINT_DST] = combine_dst; |
|
2373 imp->combine_width[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u; |
|
2374 imp->combine_width[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_u; |
|
2375 imp->combine_width[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u; |
|
2376 imp->combine_width[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_u; |
|
2377 imp->combine_width[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_u; |
|
2378 imp->combine_width[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_u; |
|
2379 imp->combine_width[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_u; |
|
2380 imp->combine_width[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_u; |
|
2381 imp->combine_width[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_u; |
|
2382 |
|
2383 imp->combine_width[PIXMAN_OP_MULTIPLY] = combine_multiply_u; |
|
2384 imp->combine_width[PIXMAN_OP_SCREEN] = combine_screen_u; |
|
2385 imp->combine_width[PIXMAN_OP_OVERLAY] = combine_overlay_u; |
|
2386 imp->combine_width[PIXMAN_OP_DARKEN] = combine_darken_u; |
|
2387 imp->combine_width[PIXMAN_OP_LIGHTEN] = combine_lighten_u; |
|
2388 imp->combine_width[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_u; |
|
2389 imp->combine_width[PIXMAN_OP_COLOR_BURN] = combine_color_burn_u; |
|
2390 imp->combine_width[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u; |
|
2391 imp->combine_width[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_u; |
|
2392 imp->combine_width[PIXMAN_OP_DIFFERENCE] = combine_difference_u; |
|
2393 imp->combine_width[PIXMAN_OP_EXCLUSION] = combine_exclusion_u; |
|
2394 imp->combine_width[PIXMAN_OP_HSL_HUE] = combine_hsl_hue_u; |
|
2395 imp->combine_width[PIXMAN_OP_HSL_SATURATION] = combine_hsl_saturation_u; |
|
2396 imp->combine_width[PIXMAN_OP_HSL_COLOR] = combine_hsl_color_u; |
|
2397 imp->combine_width[PIXMAN_OP_HSL_LUMINOSITY] = combine_hsl_luminosity_u; |
|
2398 |
|
2399 /* Component alpha combiners */ |
|
2400 imp->combine_width_ca[PIXMAN_OP_CLEAR] = combine_clear_ca; |
|
2401 imp->combine_width_ca[PIXMAN_OP_SRC] = combine_src_ca; |
|
2402 /* dest */ |
|
2403 imp->combine_width_ca[PIXMAN_OP_OVER] = combine_over_ca; |
|
2404 imp->combine_width_ca[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_ca; |
|
2405 imp->combine_width_ca[PIXMAN_OP_IN] = combine_in_ca; |
|
2406 imp->combine_width_ca[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_ca; |
|
2407 imp->combine_width_ca[PIXMAN_OP_OUT] = combine_out_ca; |
|
2408 imp->combine_width_ca[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_ca; |
|
2409 imp->combine_width_ca[PIXMAN_OP_ATOP] = combine_atop_ca; |
|
2410 imp->combine_width_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca; |
|
2411 imp->combine_width_ca[PIXMAN_OP_XOR] = combine_xor_ca; |
|
2412 imp->combine_width_ca[PIXMAN_OP_ADD] = combine_add_ca; |
|
2413 imp->combine_width_ca[PIXMAN_OP_SATURATE] = combine_saturate_ca; |
|
2414 |
|
2415 /* Disjoint CA */ |
|
2416 imp->combine_width_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear_ca; |
|
2417 imp->combine_width_ca[PIXMAN_OP_DISJOINT_SRC] = combine_src_ca; |
|
2418 imp->combine_width_ca[PIXMAN_OP_DISJOINT_DST] = combine_dst; |
|
2419 imp->combine_width_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca; |
|
2420 imp->combine_width_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_ca; |
|
2421 imp->combine_width_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca; |
|
2422 imp->combine_width_ca[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_ca; |
|
2423 imp->combine_width_ca[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_ca; |
|
2424 imp->combine_width_ca[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_ca; |
|
2425 imp->combine_width_ca[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_ca; |
|
2426 imp->combine_width_ca[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_ca; |
|
2427 imp->combine_width_ca[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_ca; |
|
2428 |
|
2429 /* Conjoint CA */ |
|
2430 imp->combine_width_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear_ca; |
|
2431 imp->combine_width_ca[PIXMAN_OP_CONJOINT_SRC] = combine_src_ca; |
|
2432 imp->combine_width_ca[PIXMAN_OP_CONJOINT_DST] = combine_dst; |
|
2433 imp->combine_width_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca; |
|
2434 imp->combine_width_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_ca; |
|
2435 imp->combine_width_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca; |
|
2436 imp->combine_width_ca[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_ca; |
|
2437 imp->combine_width_ca[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_ca; |
|
2438 imp->combine_width_ca[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_ca; |
|
2439 imp->combine_width_ca[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_ca; |
|
2440 imp->combine_width_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_ca; |
|
2441 imp->combine_width_ca[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_ca; |
|
2442 |
|
2443 imp->combine_width_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca; |
|
2444 imp->combine_width_ca[PIXMAN_OP_SCREEN] = combine_screen_ca; |
|
2445 imp->combine_width_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca; |
|
2446 imp->combine_width_ca[PIXMAN_OP_DARKEN] = combine_darken_ca; |
|
2447 imp->combine_width_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca; |
|
2448 imp->combine_width_ca[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_ca; |
|
2449 imp->combine_width_ca[PIXMAN_OP_COLOR_BURN] = combine_color_burn_ca; |
|
2450 imp->combine_width_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca; |
|
2451 imp->combine_width_ca[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_ca; |
|
2452 imp->combine_width_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca; |
|
2453 imp->combine_width_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca; |
|
2454 |
|
2455 /* It is not clear that these make sense, so make them noops for now */ |
|
2456 imp->combine_width_ca[PIXMAN_OP_HSL_HUE] = combine_dst; |
|
2457 imp->combine_width_ca[PIXMAN_OP_HSL_SATURATION] = combine_dst; |
|
2458 imp->combine_width_ca[PIXMAN_OP_HSL_COLOR] = combine_dst; |
|
2459 imp->combine_width_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst; |
|
2460 } |
|
2461 |