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