8 #include "pixman-private.h"
10 #include "pixman-combine.h"
12 /*** per channel helper functions ***/
15 combine_mask_ca (comp4_t *src, comp4_t *mask)
39 UNcx4_MUL_UNcx4 (x, a);
42 UNcx4_MUL_UNc (a, xa);
47 combine_mask_value_ca (comp4_t *src, const comp4_t *mask)
62 UNcx4_MUL_UNcx4 (x, a);
67 combine_mask_alpha_ca (const comp4_t *src, comp4_t *mask)
75 x = *(src) >> A_SHIFT;
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.
100 * All of the composing functions
103 static force_inline comp4_t
104 combine_mask (const comp4_t *src, const comp4_t *mask, int i)
110 m = *(mask + i) >> A_SHIFT;
119 UNcx4_MUL_UNc (s, m);
125 combine_clear (pixman_implementation_t *imp,
129 const comp4_t * mask,
132 memset (dest, 0, width * sizeof(comp4_t));
136 combine_dst (pixman_implementation_t *imp,
140 const comp4_t * mask,
147 combine_src_u (pixman_implementation_t *imp,
151 const comp4_t * mask,
157 memcpy (dest, src, width * sizeof (comp4_t));
160 for (i = 0; i < width; ++i)
162 comp4_t s = combine_mask (src, mask, i);
169 /* if the Src is opaque, call combine_src_u */
171 combine_over_u (pixman_implementation_t *imp,
175 const comp4_t * mask,
180 for (i = 0; i < width; ++i)
182 comp4_t s = combine_mask (src, mask, i);
183 comp4_t d = *(dest + i);
184 comp4_t ia = ALPHA_c (~s);
186 UNcx4_MUL_UNc_ADD_UNcx4 (d, ia, s);
191 /* if the Dst is opaque, this is a noop */
193 combine_over_reverse_u (pixman_implementation_t *imp,
197 const comp4_t * mask,
202 for (i = 0; i < width; ++i)
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);
212 /* if the Dst is opaque, call combine_src_u */
214 combine_in_u (pixman_implementation_t *imp,
218 const comp4_t * mask,
223 for (i = 0; i < width; ++i)
225 comp4_t s = combine_mask (src, mask, i);
226 comp4_t a = ALPHA_c (*(dest + i));
227 UNcx4_MUL_UNc (s, a);
232 /* if the Src is opaque, this is a noop */
234 combine_in_reverse_u (pixman_implementation_t *imp,
238 const comp4_t * mask,
243 for (i = 0; i < width; ++i)
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);
253 /* if the Dst is opaque, call combine_clear */
255 combine_out_u (pixman_implementation_t *imp,
259 const comp4_t * mask,
264 for (i = 0; i < width; ++i)
266 comp4_t s = combine_mask (src, mask, i);
267 comp4_t a = ALPHA_c (~*(dest + i));
268 UNcx4_MUL_UNc (s, a);
273 /* if the Src is opaque, call combine_clear */
275 combine_out_reverse_u (pixman_implementation_t *imp,
279 const comp4_t * mask,
284 for (i = 0; i < width; ++i)
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);
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 */
298 combine_atop_u (pixman_implementation_t *imp,
302 const comp4_t * mask,
307 for (i = 0; i < width; ++i)
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);
314 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (s, dest_a, d, src_ia);
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 */
323 combine_atop_reverse_u (pixman_implementation_t *imp,
327 const comp4_t * mask,
332 for (i = 0; i < width; ++i)
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);
339 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (s, dest_ia, d, src_a);
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 */
348 combine_xor_u (pixman_implementation_t *imp,
352 const comp4_t * mask,
357 for (i = 0; i < width; ++i)
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);
364 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (s, dest_ia, d, src_ia);
370 combine_add_u (pixman_implementation_t *imp,
374 const comp4_t * mask,
379 for (i = 0; i < width; ++i)
381 comp4_t s = combine_mask (src, mask, i);
382 comp4_t d = *(dest + i);
383 UNcx4_ADD_UNcx4 (d, s);
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 */
392 combine_saturate_u (pixman_implementation_t *imp,
396 const comp4_t * mask,
401 for (i = 0; i < width; ++i)
403 comp4_t s = combine_mask (src, mask, i);
404 comp4_t d = *(dest + i);
411 sa = DIV_UNc (da, sa);
412 UNcx4_MUL_UNc (s, sa);
415 UNcx4_ADD_UNcx4 (d, s);
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
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.
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)
445 * B(Dca, ad, Sca, as) = Dca.Sca
449 combine_multiply_u (pixman_implementation_t *imp,
453 const comp4_t * mask,
458 for (i = 0; i < width; ++i)
460 comp4_t s = combine_mask (src, mask, i);
461 comp4_t d = *(dest + i);
463 comp4_t src_ia = ALPHA_c (~s);
464 comp4_t dest_ia = ALPHA_c (~d);
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);
475 combine_multiply_ca (pixman_implementation_t *imp,
479 const comp4_t * mask,
484 for (i = 0; i < width; ++i)
486 comp4_t m = *(mask + i);
487 comp4_t s = *(src + i);
488 comp4_t d = *(dest + i);
490 comp4_t dest_ia = ALPHA_c (~d);
492 combine_mask_value_ca (&s, &m);
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);
502 #define PDF_SEPARABLE_BLEND_MODE(name) \
504 combine_ ## name ## _u (pixman_implementation_t *imp, \
507 const comp4_t * src, \
508 const comp4_t * mask, \
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); \
517 comp1_t da = ALPHA_c (d); \
522 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida); \
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)); \
533 combine_ ## name ## _ca (pixman_implementation_t *imp, \
536 const comp4_t * src, \
537 const comp4_t * mask, \
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); \
549 combine_mask_value_ca (&s, &m); \
552 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (result, ~m, s, ida); \
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))); \
560 *(dest + i) = result; \
566 * B(Dca, ad, Sca, as) = Dca.sa + Sca.da - Dca.Sca
568 static inline comp4_t
569 blend_screen (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
571 return DIV_ONE_UNc (sca * da + dca * sa - sca * dca);
574 PDF_SEPARABLE_BLEND_MODE (screen)
578 * B(Dca, Da, Sca, Sa) =
582 * Sa.Da - 2.(Da - Dca).(Sa - Sca)
584 static inline comp4_t
585 blend_overlay (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
592 rca = sa * da - 2 * (da - dca) * (sa - sca);
593 return DIV_ONE_UNc (rca);
596 PDF_SEPARABLE_BLEND_MODE (overlay)
600 * B(Dca, Da, Sca, Sa) = min (Sca.Da, Dca.Sa)
602 static inline comp4_t
603 blend_darken (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
609 return DIV_ONE_UNc (s > d ? d : s);
612 PDF_SEPARABLE_BLEND_MODE (darken)
616 * B(Dca, Da, Sca, Sa) = max (Sca.Da, Dca.Sa)
618 static inline comp4_t
619 blend_lighten (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
625 return DIV_ONE_UNc (s > d ? s : d);
628 PDF_SEPARABLE_BLEND_MODE (lighten)
632 * B(Dca, Da, Sca, Sa) =
638 * Sa.Da. min (1, Dca / Da / (1 - Sca/Sa))
640 static inline comp4_t
641 blend_color_dodge (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
645 return dca == 0 ? 0 : DIV_ONE_UNc (sa * da);
649 comp4_t rca = dca * sa / (sa - sca);
650 return DIV_ONE_UNc (sa * MIN (rca, da));
654 PDF_SEPARABLE_BLEND_MODE (color_dodge)
658 * B(Dca, Da, Sca, Sa) =
664 * Sa.Da.(1 - min (1, (1 - Dca/Da).Sa / Sca))
666 static inline comp4_t
667 blend_color_burn (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
671 return dca < da ? 0 : DIV_ONE_UNc (sa * da);
675 comp4_t rca = (da - dca) * sa / sca;
676 return DIV_ONE_UNc (sa * (MAX (rca, da) - rca));
680 PDF_SEPARABLE_BLEND_MODE (color_burn)
684 * B(Dca, Da, Sca, Sa) =
688 * Sa.Da - 2.(Da - Dca).(Sa - Sca)
690 static inline comp4_t
691 blend_hard_light (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
694 return DIV_ONE_UNc (2 * sca * dca);
696 return DIV_ONE_UNc (sa * da - 2 * (da - dca) * (sa - sca));
699 PDF_SEPARABLE_BLEND_MODE (hard_light)
703 * B(Dca, Da, 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)
709 * (Dca.Sa + (SQRT (Dca/Da).Da - Dca).(2.Sca - Sa))
711 static inline comp4_t
712 blend_soft_light (comp4_t dca_org,
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);
728 rca = dca * sa - dca * (da - dca) * (sa - 2 * sca) / da;
734 else if (4 * dca <= da)
737 (2 * sca - sa) * dca * ((16 * dca / da - 12) * dca / da + 3);
741 rca = dca * sa + (sqrt (dca * da) - dca) * (2 * sca - sa);
743 return rca * MASK + 0.5;
746 PDF_SEPARABLE_BLEND_MODE (soft_light)
750 * B(Dca, Da, Sca, Sa) = abs (Dca.Sa - Sca.Da)
752 static inline comp4_t
753 blend_difference (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
755 comp4_t dcasa = dca * sa;
756 comp4_t scada = sca * da;
759 return DIV_ONE_UNc (dcasa - scada);
761 return DIV_ONE_UNc (scada - dcasa);
764 PDF_SEPARABLE_BLEND_MODE (difference)
768 * B(Dca, Da, Sca, Sa) = (Sca.Da + Dca.Sa - 2.Sca.Dca)
771 /* This can be made faster by writing it directly and not using
772 * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */
774 static inline comp4_t
775 blend_exclusion (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
777 return DIV_ONE_UNc (sca * da + dca * sa - 2 * dca * sca);
780 PDF_SEPARABLE_BLEND_MODE (exclusion)
782 #undef PDF_SEPARABLE_BLEND_MODE
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.
789 * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue
796 * C = l + ( ( ( C – l ) × l ) ⁄ ( l – min ) )
798 * C = l + ( ( ( C – l ) × ( 1 – l ) ) ⁄ ( max – l ) )
804 * return clip_color (C)
806 * SAT (C) = CH_MAX (C) - CH_MIN (C)
810 * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) )
818 /* For premultiplied colors, we need to know what happens when C is
819 * multiplied by a real number. LUM and SAT are linear:
821 * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C)
823 * If we extend clip_color with an extra argument a and change
831 * then clip_color is also linear:
833 * r * clip_color (C, a) = clip_color (r_c, ra);
837 * Similarly, we can extend set_lum with an extra argument that is just passed
840 * r * set_lum ( C, l, a)
842 * = r × clip_color ( C + l - LUM (C), a)
844 * = clip_color ( r * C + r × l - r * LUM (C), r * a)
846 * = set_lum ( r * C, r * l, r * a)
850 * r * set_sat (C, s) = set_sat (x * C, r * s)
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:
855 * r * set_sat (C, s) = set_sat (r_c, rs)
859 /* So, for the non-separable PDF blend modes, we have (using s, d for
860 * non-premultiplied colors, and S, D for premultiplied:
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)
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)
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))
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)
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))
897 #define PDF_NON_SEPARABLE_BLEND_MODE(name) \
899 combine_ ## name ## _u (pixman_implementation_t *imp, \
902 const comp4_t *src, \
903 const comp4_t *mask, \
907 for (i = 0; i < width; ++i) \
909 comp4_t s = combine_mask (src, mask, i); \
910 comp4_t d = *(dest + i); \
911 comp1_t sa = ALPHA_c (s); \
913 comp1_t da = ALPHA_c (d); \
916 comp4_t sc[3], dc[3], c[3]; \
919 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida); \
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); \
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])); \
937 set_lum (comp4_t dest[3], comp4_t src[3], comp4_t sa, comp4_t lum)
939 double a, l, min, max;
942 a = sa * (1.0 / MASK);
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);
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);
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);
990 dest[0] = tmp[0] * MASK + 0.5;
991 dest[1] = tmp[1] * MASK + 0.5;
992 dest[2] = tmp[2] * MASK + 0.5;
996 set_sat (comp4_t dest[3], comp4_t src[3], comp4_t sat)
1001 if (src[0] > src[1])
1003 if (src[0] > src[2])
1006 if (src[1] > src[2])
1026 if (src[0] > src[2])
1035 if (src[1] > src[2])
1052 dest[id[1]] = (dest[id[1]] - min) * sat / (max - min);
1058 dest[0] = dest[1] = dest[2] = 0;
1064 * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb))
1067 blend_hsl_hue (comp4_t c[3],
1076 set_sat (c, c, SAT (dc) * sa);
1077 set_lum (c, c, sa * da, LUM (dc) * sa);
1080 PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue)
1084 * B(Cb, Cs) = set_lum (set_sat (Cb, SAT (Cs)), LUM (Cb))
1087 blend_hsl_saturation (comp4_t c[3],
1096 set_sat (c, c, SAT (sc) * da);
1097 set_lum (c, c, sa * da, LUM (dc) * sa);
1100 PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation)
1104 * B(Cb, Cs) = set_lum (Cs, LUM (Cb))
1107 blend_hsl_color (comp4_t c[3],
1116 set_lum (c, c, sa * da, LUM (dc) * sa);
1119 PDF_NON_SEPARABLE_BLEND_MODE (hsl_color)
1123 * B(Cb, Cs) = set_lum (Cb, LUM (Cs))
1126 blend_hsl_luminosity (comp4_t c[3],
1135 set_lum (c, c, sa * da, LUM (sc) * da);
1138 PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
1144 #undef PDF_NON_SEPARABLE_BLEND_MODE
1146 /* All of the disjoint/conjoint composing functions
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.
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)
1168 * See http://marc.info/?l=xfree-render&m=99792000027857&w=2 for more
1169 * information about these operators.
1172 #define COMBINE_A_OUT 1
1173 #define COMBINE_A_IN 2
1174 #define COMBINE_B_OUT 4
1175 #define COMBINE_B_IN 8
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)
1186 /* portion covered by a but not b */
1188 combine_disjoint_out_part (comp1_t a, comp1_t b)
1190 /* min (1, (1-b) / a) */
1193 if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
1194 return MASK; /* 1 */
1195 return DIV_UNc (b, a); /* (1-b) / a */
1198 /* portion covered by both a and b */
1200 combine_disjoint_in_part (comp1_t a, comp1_t b)
1202 /* max (1-(1-b)/a,0) */
1203 /* = - min ((1-b)/a - 1, 0) */
1204 /* = 1 - min (1, (1-b)/a) */
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 */
1212 /* portion covered by a but not b */
1214 combine_conjoint_out_part (comp1_t a, comp1_t b)
1217 /* = 1-min(b/a,1) */
1219 /* min (1, (1-b) / a) */
1221 if (b >= a) /* b >= a -> b/a >= 1 */
1222 return 0x00; /* 0 */
1223 return ~DIV_UNc(b, a); /* 1 - b/a */
1226 /* portion covered by both a and b */
1228 combine_conjoint_in_part (comp1_t a, comp1_t b)
1232 if (b >= a) /* b >= a -> b/a >= 1 */
1233 return MASK; /* 1 */
1234 return DIV_UNc (b, a); /* b/a */
1237 #define GET_COMP(v, i) ((comp2_t) (comp1_t) ((v) >> i))
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))
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))
1250 combine_disjoint_general_u (comp4_t * dest,
1252 const comp4_t *mask,
1258 for (i = 0; i < width; ++i)
1260 comp4_t s = combine_mask (src, mask, i);
1261 comp4_t d = *(dest + i);
1263 comp2_t Fa, Fb, t, u, v;
1264 comp1_t sa = s >> A_SHIFT;
1265 comp1_t da = d >> A_SHIFT;
1267 switch (combine & COMBINE_A)
1274 Fa = combine_disjoint_out_part (sa, da);
1278 Fa = combine_disjoint_in_part (sa, da);
1286 switch (combine & COMBINE_B)
1293 Fb = combine_disjoint_out_part (da, sa);
1297 Fb = combine_disjoint_in_part (da, sa);
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);
1314 combine_disjoint_over_u (pixman_implementation_t *imp,
1317 const comp4_t * src,
1318 const comp4_t * mask,
1323 for (i = 0; i < width; ++i)
1325 comp4_t s = combine_mask (src, mask, i);
1326 comp2_t a = s >> A_SHIFT;
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);
1340 combine_disjoint_in_u (pixman_implementation_t *imp,
1343 const comp4_t * src,
1344 const comp4_t * mask,
1347 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
1351 combine_disjoint_in_reverse_u (pixman_implementation_t *imp,
1354 const comp4_t * src,
1355 const comp4_t * mask,
1358 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
1362 combine_disjoint_out_u (pixman_implementation_t *imp,
1365 const comp4_t * src,
1366 const comp4_t * mask,
1369 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
1373 combine_disjoint_out_reverse_u (pixman_implementation_t *imp,
1376 const comp4_t * src,
1377 const comp4_t * mask,
1380 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
1384 combine_disjoint_atop_u (pixman_implementation_t *imp,
1387 const comp4_t * src,
1388 const comp4_t * mask,
1391 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
1395 combine_disjoint_atop_reverse_u (pixman_implementation_t *imp,
1398 const comp4_t * src,
1399 const comp4_t * mask,
1402 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
1406 combine_disjoint_xor_u (pixman_implementation_t *imp,
1409 const comp4_t * src,
1410 const comp4_t * mask,
1413 combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR);
1417 combine_conjoint_general_u (comp4_t * dest,
1419 const comp4_t *mask,
1425 for (i = 0; i < width; ++i)
1427 comp4_t s = combine_mask (src, mask, i);
1428 comp4_t d = *(dest + i);
1430 comp2_t Fa, Fb, t, u, v;
1431 comp1_t sa = s >> A_SHIFT;
1432 comp1_t da = d >> A_SHIFT;
1434 switch (combine & COMBINE_A)
1441 Fa = combine_conjoint_out_part (sa, da);
1445 Fa = combine_conjoint_in_part (sa, da);
1453 switch (combine & COMBINE_B)
1460 Fb = combine_conjoint_out_part (da, sa);
1464 Fb = combine_conjoint_in_part (da, sa);
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);
1484 combine_conjoint_over_u (pixman_implementation_t *imp,
1487 const comp4_t * src,
1488 const comp4_t * mask,
1491 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER);
1495 combine_conjoint_over_reverse_u (pixman_implementation_t *imp,
1498 const comp4_t * src,
1499 const comp4_t * mask,
1502 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER);
1506 combine_conjoint_in_u (pixman_implementation_t *imp,
1509 const comp4_t * src,
1510 const comp4_t * mask,
1513 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
1517 combine_conjoint_in_reverse_u (pixman_implementation_t *imp,
1520 const comp4_t * src,
1521 const comp4_t * mask,
1524 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
1528 combine_conjoint_out_u (pixman_implementation_t *imp,
1531 const comp4_t * src,
1532 const comp4_t * mask,
1535 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
1539 combine_conjoint_out_reverse_u (pixman_implementation_t *imp,
1542 const comp4_t * src,
1543 const comp4_t * mask,
1546 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
1550 combine_conjoint_atop_u (pixman_implementation_t *imp,
1553 const comp4_t * src,
1554 const comp4_t * mask,
1557 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
1561 combine_conjoint_atop_reverse_u (pixman_implementation_t *imp,
1564 const comp4_t * src,
1565 const comp4_t * mask,
1568 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
1572 combine_conjoint_xor_u (pixman_implementation_t *imp,
1575 const comp4_t * src,
1576 const comp4_t * mask,
1579 combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR);
1582 /************************************************************************/
1583 /*********************** Per Channel functions **************************/
1584 /************************************************************************/
1587 combine_clear_ca (pixman_implementation_t *imp,
1590 const comp4_t * src,
1591 const comp4_t * mask,
1594 memset (dest, 0, width * sizeof(comp4_t));
1598 combine_src_ca (pixman_implementation_t *imp,
1601 const comp4_t * src,
1602 const comp4_t * mask,
1607 for (i = 0; i < width; ++i)
1609 comp4_t s = *(src + i);
1610 comp4_t m = *(mask + i);
1612 combine_mask_value_ca (&s, &m);
1619 combine_over_ca (pixman_implementation_t *imp,
1622 const comp4_t * src,
1623 const comp4_t * mask,
1628 for (i = 0; i < width; ++i)
1630 comp4_t s = *(src + i);
1631 comp4_t m = *(mask + i);
1634 combine_mask_ca (&s, &m);
1639 comp4_t d = *(dest + i);
1640 UNcx4_MUL_UNcx4_ADD_UNcx4 (d, a, s);
1649 combine_over_reverse_ca (pixman_implementation_t *imp,
1652 const comp4_t * src,
1653 const comp4_t * mask,
1658 for (i = 0; i < width; ++i)
1660 comp4_t d = *(dest + i);
1661 comp4_t a = ~d >> A_SHIFT;
1665 comp4_t s = *(src + i);
1666 comp4_t m = *(mask + i);
1668 UNcx4_MUL_UNcx4 (s, m);
1669 UNcx4_MUL_UNc_ADD_UNcx4 (s, a, d);
1677 combine_in_ca (pixman_implementation_t *imp,
1680 const comp4_t * src,
1681 const comp4_t * mask,
1686 for (i = 0; i < width; ++i)
1688 comp4_t d = *(dest + i);
1689 comp2_t a = d >> A_SHIFT;
1694 comp4_t m = *(mask + i);
1697 combine_mask_value_ca (&s, &m);
1700 UNcx4_MUL_UNc (s, a);
1708 combine_in_reverse_ca (pixman_implementation_t *imp,
1711 const comp4_t * src,
1712 const comp4_t * mask,
1717 for (i = 0; i < width; ++i)
1719 comp4_t s = *(src + i);
1720 comp4_t m = *(mask + i);
1723 combine_mask_alpha_ca (&s, &m);
1733 UNcx4_MUL_UNcx4 (d, a);
1742 combine_out_ca (pixman_implementation_t *imp,
1745 const comp4_t * src,
1746 const comp4_t * mask,
1751 for (i = 0; i < width; ++i)
1753 comp4_t d = *(dest + i);
1754 comp2_t a = ~d >> A_SHIFT;
1759 comp4_t m = *(mask + i);
1762 combine_mask_value_ca (&s, &m);
1765 UNcx4_MUL_UNc (s, a);
1773 combine_out_reverse_ca (pixman_implementation_t *imp,
1776 const comp4_t * src,
1777 const comp4_t * mask,
1782 for (i = 0; i < width; ++i)
1784 comp4_t s = *(src + i);
1785 comp4_t m = *(mask + i);
1788 combine_mask_alpha_ca (&s, &m);
1798 UNcx4_MUL_UNcx4 (d, a);
1807 combine_atop_ca (pixman_implementation_t *imp,
1810 const comp4_t * src,
1811 const comp4_t * mask,
1816 for (i = 0; i < width; ++i)
1818 comp4_t d = *(dest + i);
1819 comp4_t s = *(src + i);
1820 comp4_t m = *(mask + i);
1822 comp2_t as = d >> A_SHIFT;
1824 combine_mask_ca (&s, &m);
1828 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (d, ad, s, as);
1835 combine_atop_reverse_ca (pixman_implementation_t *imp,
1838 const comp4_t * src,
1839 const comp4_t * mask,
1844 for (i = 0; i < width; ++i)
1846 comp4_t d = *(dest + i);
1847 comp4_t s = *(src + i);
1848 comp4_t m = *(mask + i);
1850 comp2_t as = ~d >> A_SHIFT;
1852 combine_mask_ca (&s, &m);
1856 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (d, ad, s, as);
1863 combine_xor_ca (pixman_implementation_t *imp,
1866 const comp4_t * src,
1867 const comp4_t * mask,
1872 for (i = 0; i < width; ++i)
1874 comp4_t d = *(dest + i);
1875 comp4_t s = *(src + i);
1876 comp4_t m = *(mask + i);
1878 comp2_t as = ~d >> A_SHIFT;
1880 combine_mask_ca (&s, &m);
1884 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (d, ad, s, as);
1891 combine_add_ca (pixman_implementation_t *imp,
1894 const comp4_t * src,
1895 const comp4_t * mask,
1900 for (i = 0; i < width; ++i)
1902 comp4_t s = *(src + i);
1903 comp4_t m = *(mask + i);
1904 comp4_t d = *(dest + i);
1906 combine_mask_value_ca (&s, &m);
1908 UNcx4_ADD_UNcx4 (d, s);
1915 combine_saturate_ca (pixman_implementation_t *imp,
1918 const comp4_t * src,
1919 const comp4_t * mask,
1924 for (i = 0; i < width; ++i)
1927 comp2_t sa, sr, sg, sb, da;
1935 combine_mask_ca (&s, &m);
1937 sa = (m >> A_SHIFT);
1938 sr = (m >> R_SHIFT) & MASK;
1939 sg = (m >> G_SHIFT) & MASK;
1944 m = ADD (s, d, 0, t);
1946 m = GENERIC (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v);
1949 n = ADD (s, d, G_SHIFT, t);
1951 n = GENERIC (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v);
1954 o = ADD (s, d, R_SHIFT, t);
1956 o = GENERIC (s, d, R_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v);
1959 p = ADD (s, d, A_SHIFT, t);
1961 p = GENERIC (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v);
1963 *(dest + i) = m | n | o | p;
1968 combine_disjoint_general_ca (comp4_t * dest,
1970 const comp4_t *mask,
1976 for (i = 0; i < width; ++i)
1990 combine_mask_ca (&s, &m);
1994 switch (combine & COMBINE_A)
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;
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;
2021 switch (combine & COMBINE_B)
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;
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;
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);
2059 combine_disjoint_over_ca (pixman_implementation_t *imp,
2062 const comp4_t * src,
2063 const comp4_t * mask,
2066 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
2070 combine_disjoint_in_ca (pixman_implementation_t *imp,
2073 const comp4_t * src,
2074 const comp4_t * mask,
2077 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
2081 combine_disjoint_in_reverse_ca (pixman_implementation_t *imp,
2084 const comp4_t * src,
2085 const comp4_t * mask,
2088 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
2092 combine_disjoint_out_ca (pixman_implementation_t *imp,
2095 const comp4_t * src,
2096 const comp4_t * mask,
2099 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
2103 combine_disjoint_out_reverse_ca (pixman_implementation_t *imp,
2106 const comp4_t * src,
2107 const comp4_t * mask,
2110 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
2114 combine_disjoint_atop_ca (pixman_implementation_t *imp,
2117 const comp4_t * src,
2118 const comp4_t * mask,
2121 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
2125 combine_disjoint_atop_reverse_ca (pixman_implementation_t *imp,
2128 const comp4_t * src,
2129 const comp4_t * mask,
2132 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
2136 combine_disjoint_xor_ca (pixman_implementation_t *imp,
2139 const comp4_t * src,
2140 const comp4_t * mask,
2143 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
2147 combine_conjoint_general_ca (comp4_t * dest,
2149 const comp4_t *mask,
2155 for (i = 0; i < width; ++i)
2169 combine_mask_ca (&s, &m);
2173 switch (combine & COMBINE_A)
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;
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;
2200 switch (combine & COMBINE_B)
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;
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;
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);
2238 combine_conjoint_over_ca (pixman_implementation_t *imp,
2241 const comp4_t * src,
2242 const comp4_t * mask,
2245 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
2249 combine_conjoint_over_reverse_ca (pixman_implementation_t *imp,
2252 const comp4_t * src,
2253 const comp4_t * mask,
2256 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER);
2260 combine_conjoint_in_ca (pixman_implementation_t *imp,
2263 const comp4_t * src,
2264 const comp4_t * mask,
2267 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
2271 combine_conjoint_in_reverse_ca (pixman_implementation_t *imp,
2274 const comp4_t * src,
2275 const comp4_t * mask,
2278 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
2282 combine_conjoint_out_ca (pixman_implementation_t *imp,
2285 const comp4_t * src,
2286 const comp4_t * mask,
2289 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
2293 combine_conjoint_out_reverse_ca (pixman_implementation_t *imp,
2296 const comp4_t * src,
2297 const comp4_t * mask,
2300 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
2304 combine_conjoint_atop_ca (pixman_implementation_t *imp,
2307 const comp4_t * src,
2308 const comp4_t * mask,
2311 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
2315 combine_conjoint_atop_reverse_ca (pixman_implementation_t *imp,
2318 const comp4_t * src,
2319 const comp4_t * mask,
2322 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
2326 combine_conjoint_xor_ca (pixman_implementation_t *imp,
2329 const comp4_t * src,
2330 const comp4_t * mask,
2333 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
2337 _pixman_setup_combiner_functions_width (pixman_implementation_t *imp)
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;