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;
93 * There are two ways of handling alpha -- either as a single unified value or
94 * a separate value for each component, hence each macro must have two
95 * versions. The unified alpha version has a 'U' at the end of the name,
96 * the component version has a 'C'. Similarly, functions which deal with
97 * this difference will have two versions using the same convention.
101 * All of the composing functions
104 static force_inline comp4_t
105 combine_mask (const comp4_t *src, const comp4_t *mask, int i)
111 m = *(mask + i) >> A_SHIFT;
120 UNcx4_MUL_UNc (s, m);
126 combine_clear (pixman_implementation_t *imp,
130 const comp4_t * mask,
133 memset (dest, 0, width * sizeof(comp4_t));
137 combine_src_u (pixman_implementation_t *imp,
141 const comp4_t * mask,
147 memcpy (dest, src, width * sizeof (comp4_t));
150 for (i = 0; i < width; ++i)
152 comp4_t s = combine_mask (src, mask, i);
159 /* if the Src is opaque, call combine_src_u */
161 combine_over_u (pixman_implementation_t *imp,
165 const comp4_t * mask,
170 for (i = 0; i < width; ++i)
172 comp4_t s = combine_mask (src, mask, i);
173 comp4_t d = *(dest + i);
174 comp4_t ia = ALPHA_c (~s);
176 UNcx4_MUL_UNc_ADD_UNcx4 (d, ia, s);
181 /* if the Dst is opaque, this is a noop */
183 combine_over_reverse_u (pixman_implementation_t *imp,
187 const comp4_t * mask,
192 for (i = 0; i < width; ++i)
194 comp4_t s = combine_mask (src, mask, i);
195 comp4_t d = *(dest + i);
196 comp4_t ia = ALPHA_c (~*(dest + i));
197 UNcx4_MUL_UNc_ADD_UNcx4 (s, ia, d);
202 /* if the Dst is opaque, call combine_src_u */
204 combine_in_u (pixman_implementation_t *imp,
208 const comp4_t * mask,
213 for (i = 0; i < width; ++i)
215 comp4_t s = combine_mask (src, mask, i);
216 comp4_t a = ALPHA_c (*(dest + i));
217 UNcx4_MUL_UNc (s, a);
222 /* if the Src is opaque, this is a noop */
224 combine_in_reverse_u (pixman_implementation_t *imp,
228 const comp4_t * mask,
233 for (i = 0; i < width; ++i)
235 comp4_t s = combine_mask (src, mask, i);
236 comp4_t d = *(dest + i);
237 comp4_t a = ALPHA_c (s);
238 UNcx4_MUL_UNc (d, a);
243 /* if the Dst is opaque, call combine_clear */
245 combine_out_u (pixman_implementation_t *imp,
249 const comp4_t * mask,
254 for (i = 0; i < width; ++i)
256 comp4_t s = combine_mask (src, mask, i);
257 comp4_t a = ALPHA_c (~*(dest + i));
258 UNcx4_MUL_UNc (s, a);
263 /* if the Src is opaque, call combine_clear */
265 combine_out_reverse_u (pixman_implementation_t *imp,
269 const comp4_t * mask,
274 for (i = 0; i < width; ++i)
276 comp4_t s = combine_mask (src, mask, i);
277 comp4_t d = *(dest + i);
278 comp4_t a = ALPHA_c (~s);
279 UNcx4_MUL_UNc (d, a);
284 /* if the Src is opaque, call combine_in_u */
285 /* if the Dst is opaque, call combine_over_u */
286 /* if both the Src and Dst are opaque, call combine_src_u */
288 combine_atop_u (pixman_implementation_t *imp,
292 const comp4_t * mask,
297 for (i = 0; i < width; ++i)
299 comp4_t s = combine_mask (src, mask, i);
300 comp4_t d = *(dest + i);
301 comp4_t dest_a = ALPHA_c (d);
302 comp4_t src_ia = ALPHA_c (~s);
304 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (s, dest_a, d, src_ia);
309 /* if the Src is opaque, call combine_over_reverse_u */
310 /* if the Dst is opaque, call combine_in_reverse_u */
311 /* if both the Src and Dst are opaque, call combine_dst_u */
313 combine_atop_reverse_u (pixman_implementation_t *imp,
317 const comp4_t * mask,
322 for (i = 0; i < width; ++i)
324 comp4_t s = combine_mask (src, mask, i);
325 comp4_t d = *(dest + i);
326 comp4_t src_a = ALPHA_c (s);
327 comp4_t dest_ia = ALPHA_c (~d);
329 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (s, dest_ia, d, src_a);
334 /* if the Src is opaque, call combine_over_u */
335 /* if the Dst is opaque, call combine_over_reverse_u */
336 /* if both the Src and Dst are opaque, call combine_clear */
338 combine_xor_u (pixman_implementation_t *imp,
342 const comp4_t * mask,
347 for (i = 0; i < width; ++i)
349 comp4_t s = combine_mask (src, mask, i);
350 comp4_t d = *(dest + i);
351 comp4_t src_ia = ALPHA_c (~s);
352 comp4_t dest_ia = ALPHA_c (~d);
354 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (s, dest_ia, d, src_ia);
360 combine_add_u (pixman_implementation_t *imp,
364 const comp4_t * mask,
369 for (i = 0; i < width; ++i)
371 comp4_t s = combine_mask (src, mask, i);
372 comp4_t d = *(dest + i);
373 UNcx4_ADD_UNcx4 (d, s);
378 /* if the Src is opaque, call combine_add_u */
379 /* if the Dst is opaque, call combine_add_u */
380 /* if both the Src and Dst are opaque, call combine_add_u */
382 combine_saturate_u (pixman_implementation_t *imp,
386 const comp4_t * mask,
391 for (i = 0; i < width; ++i)
393 comp4_t s = combine_mask (src, mask, i);
394 comp4_t d = *(dest + i);
401 sa = DIV_UNc (da, sa);
402 UNcx4_MUL_UNc (s, sa);
405 UNcx4_ADD_UNcx4 (d, s);
412 * The following blend modes have been taken from the PDF ISO 32000
413 * specification, which at this point in time is available from
414 * http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf
415 * The relevant chapters are 11.3.5 and 11.3.6.
416 * The formula for computing the final pixel color given in 11.3.6 is:
417 * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs)
418 * with B() being the blend function.
419 * Note that OVER is a special case of this operation, using B(Cb, Cs) = Cs
421 * These blend modes should match the SVG filter draft specification, as
422 * it has been designed to mirror ISO 32000. Note that at the current point
423 * no released draft exists that shows this, as the formulas have not been
424 * updated yet after the release of ISO 32000.
426 * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and
427 * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an
428 * argument. Note that this implementation operates on premultiplied colors,
429 * while the PDF specification does not. Therefore the code uses the formula
430 * ar.Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
435 * B(Dca, ad, Sca, as) = Dca.Sca
439 combine_multiply_u (pixman_implementation_t *imp,
443 const comp4_t * mask,
448 for (i = 0; i < width; ++i)
450 comp4_t s = combine_mask (src, mask, i);
451 comp4_t d = *(dest + i);
453 comp4_t src_ia = ALPHA_c (~s);
454 comp4_t dest_ia = ALPHA_c (~d);
456 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (ss, dest_ia, d, src_ia);
457 UNcx4_MUL_UNcx4 (d, s);
458 UNcx4_ADD_UNcx4 (d, ss);
465 combine_multiply_ca (pixman_implementation_t *imp,
469 const comp4_t * mask,
474 for (i = 0; i < width; ++i)
476 comp4_t m = *(mask + i);
477 comp4_t s = *(src + i);
478 comp4_t d = *(dest + i);
480 comp4_t dest_ia = ALPHA_c (~d);
482 combine_mask_value_ca (&s, &m);
484 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (r, ~m, s, dest_ia);
485 UNcx4_MUL_UNcx4 (d, s);
486 UNcx4_ADD_UNcx4 (r, d);
492 #define PDF_SEPARABLE_BLEND_MODE(name) \
494 combine_ ## name ## _u (pixman_implementation_t *imp, \
497 const comp4_t * src, \
498 const comp4_t * mask, \
502 for (i = 0; i < width; ++i) { \
503 comp4_t s = combine_mask (src, mask, i); \
504 comp4_t d = *(dest + i); \
505 comp1_t sa = ALPHA_c (s); \
507 comp1_t da = ALPHA_c (d); \
512 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida); \
514 *(dest + i) = result + \
515 (DIV_ONE_UNc (sa * da) << A_SHIFT) + \
516 (blend_ ## name (RED_c (d), da, RED_c (s), sa) << R_SHIFT) + \
517 (blend_ ## name (GREEN_c (d), da, GREEN_c (s), sa) << G_SHIFT) + \
518 (blend_ ## name (BLUE_c (d), da, BLUE_c (s), sa)); \
523 combine_ ## name ## _ca (pixman_implementation_t *imp, \
526 const comp4_t * src, \
527 const comp4_t * mask, \
531 for (i = 0; i < width; ++i) { \
532 comp4_t m = *(mask + i); \
533 comp4_t s = *(src + i); \
534 comp4_t d = *(dest + i); \
535 comp1_t da = ALPHA_c (d); \
539 combine_mask_value_ca (&s, &m); \
542 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (result, ~m, s, ida); \
545 (DIV_ONE_UNc (ALPHA_c (m) * da) << A_SHIFT) + \
546 (blend_ ## name (RED_c (d), da, RED_c (s), RED_c (m)) << R_SHIFT) + \
547 (blend_ ## name (GREEN_c (d), da, GREEN_c (s), GREEN_c (m)) << G_SHIFT) + \
548 (blend_ ## name (BLUE_c (d), da, BLUE_c (s), BLUE_c (m))); \
550 *(dest + i) = result; \
556 * B(Dca, ad, Sca, as) = Dca.sa + Sca.da - Dca.Sca
558 static inline comp4_t
559 blend_screen (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
561 return DIV_ONE_UNc (sca * da + dca * sa - sca * dca);
564 PDF_SEPARABLE_BLEND_MODE (screen)
568 * B(Dca, Da, Sca, Sa) =
572 * Sa.Da - 2.(Da - Dca).(Sa - Sca)
574 static inline comp4_t
575 blend_overlay (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
582 rca = sa * da - 2 * (da - dca) * (sa - sca);
583 return DIV_ONE_UNc (rca);
586 PDF_SEPARABLE_BLEND_MODE (overlay)
590 * B(Dca, Da, Sca, Sa) = min (Sca.Da, Dca.Sa)
592 static inline comp4_t
593 blend_darken (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
599 return DIV_ONE_UNc (s > d ? d : s);
602 PDF_SEPARABLE_BLEND_MODE (darken)
606 * B(Dca, Da, Sca, Sa) = max (Sca.Da, Dca.Sa)
608 static inline comp4_t
609 blend_lighten (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
615 return DIV_ONE_UNc (s > d ? s : d);
618 PDF_SEPARABLE_BLEND_MODE (lighten)
622 * B(Dca, Da, Sca, Sa) =
628 * Sa.Da. min (1, Dca / Da / (1 - Sca/Sa))
630 static inline comp4_t
631 blend_color_dodge (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
635 return dca == 0 ? 0 : DIV_ONE_UNc (sa * da);
639 comp4_t rca = dca * sa / (sa - sca);
640 return DIV_ONE_UNc (sa * MIN (rca, da));
644 PDF_SEPARABLE_BLEND_MODE (color_dodge)
648 * B(Dca, Da, Sca, Sa) =
652 * Sa.Da.(1 - min (1, (1 - Dca/Da).Sa / Sca))
654 static inline comp4_t
655 blend_color_burn (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
659 return dca < da ? 0 : DIV_ONE_UNc (sa * da);
663 comp4_t sada = sa * da;
664 comp4_t rca = (da - dca) * sa * sa / sca;
665 return DIV_ONE_UNc (rca > sada ? 0 : sada - rca);
669 PDF_SEPARABLE_BLEND_MODE (color_burn)
673 * B(Dca, Da, Sca, Sa) =
677 * Sa.Da - 2.(Da - Dca).(Sa - Sca)
679 static inline comp4_t
680 blend_hard_light (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
683 return DIV_ONE_UNc (2 * sca * dca);
685 return DIV_ONE_UNc (sa * da - 2 * (da - dca) * (sa - sca));
688 PDF_SEPARABLE_BLEND_MODE (hard_light)
692 * B(Dca, Da, Sca, Sa) =
694 * Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa))
695 * otherwise if Dca.4 <= Da
696 * Dca.(Sa + (2.Sca - Sa).((16.Dca/Da - 12).Dca/Da + 3)
698 * (Dca.Sa + (SQRT (Dca/Da).Da - Dca).(2.Sca - Sa))
700 static inline comp4_t
701 blend_soft_light (comp4_t dca_org,
706 double dca = dca_org * (1.0 / MASK);
707 double da = da_org * (1.0 / MASK);
708 double sca = sca_org * (1.0 / MASK);
709 double sa = sa_org * (1.0 / MASK);
717 rca = dca * sa - dca * (da - dca) * (sa - 2 * sca) / da;
723 else if (4 * dca <= da)
726 (2 * sca - sa) * dca * ((16 * dca / da - 12) * dca / da + 3);
730 rca = dca * sa + (sqrt (dca * da) - dca) * (2 * sca - sa);
732 return rca * MASK + 0.5;
735 PDF_SEPARABLE_BLEND_MODE (soft_light)
739 * B(Dca, Da, Sca, Sa) = abs (Dca.Sa - Sca.Da)
741 static inline comp4_t
742 blend_difference (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
744 comp4_t dcasa = dca * sa;
745 comp4_t scada = sca * da;
748 return DIV_ONE_UNc (dcasa - scada);
750 return DIV_ONE_UNc (scada - dcasa);
753 PDF_SEPARABLE_BLEND_MODE (difference)
757 * B(Dca, Da, Sca, Sa) = (Sca.Da + Dca.Sa - 2.Sca.Dca)
760 /* This can be made faster by writing it directly and not using
761 * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */
763 static inline comp4_t
764 blend_exclusion (comp4_t dca, comp4_t da, comp4_t sca, comp4_t sa)
766 return DIV_ONE_UNc (sca * da + dca * sa - 2 * dca * sca);
769 PDF_SEPARABLE_BLEND_MODE (exclusion)
771 #undef PDF_SEPARABLE_BLEND_MODE
774 * PDF nonseperable blend modes are implemented using the following functions
775 * to operate in Hsl space, with Cmax, Cmid, Cmin referring to the max, mid
776 * and min value of the red, green and blue components.
778 * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue
785 * C = l + ( ( ( C – l ) × l ) ⁄ ( l – min ) )
787 * C = l + ( ( ( C – l ) × ( 1 – l ) ) ⁄ ( max – l ) )
793 * return clip_color (C)
795 * SAT (C) = CH_MAX (C) - CH_MIN (C)
799 * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) )
807 /* For premultiplied colors, we need to know what happens when C is
808 * multiplied by a real number. LUM and SAT are linear:
810 * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C)
812 * If we extend clip_color with an extra argument a and change
820 * then clip_color is also linear:
822 * r * clip_color (C, a) = clip_color (r_c, ra);
826 * Similarly, we can extend set_lum with an extra argument that is just passed
829 * r * set_lum ( C, l, a)
831 * = r × clip_color ( C + l - LUM (C), a)
833 * = clip_color ( r * C + r × l - r * LUM (C), r * a)
835 * = set_lum ( r * C, r * l, r * a)
839 * r * set_sat (C, s) = set_sat (x * C, r * s)
841 * The above holds for all non-zero x, because they x'es in the fraction for
842 * C_mid cancel out. Specifically, it holds for x = r:
844 * r * set_sat (C, s) = set_sat (r_c, rs)
848 /* So, for the non-separable PDF blend modes, we have (using s, d for
849 * non-premultiplied colors, and S, D for premultiplied:
853 * a_s * a_d * B(s, d)
854 * = a_s * a_d * set_lum (S/a_s, LUM (D/a_d), 1)
855 * = set_lum (S * a_d, a_s * LUM (D), a_s * a_d)
860 * a_s * a_d * B(s, d)
861 * = a_s * a_d * set_lum (D/a_d, LUM(S/a_s), 1)
862 * = set_lum (a_s * D, a_d * LUM(S), a_s * a_d)
867 * a_s * a_d * B(s, d)
868 * = a_s * a_d * set_lum (set_sat (D/a_d, SAT (S/a_s)), LUM (D/a_d), 1)
869 * = set_lum (a_s * a_d * set_sat (D/a_d, SAT (S/a_s)),
870 * a_s * LUM (D), a_s * a_d)
871 * = set_lum (set_sat (a_s * D, a_d * SAT (S), a_s * LUM (D), a_s * a_d))
875 * a_s * a_d * B(s, d)
876 * = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1)
877 * = a_s * a_d * set_lum (set_sat (a_d * S, a_s * SAT (D)),
878 * a_s * LUM (D), a_s * a_d)
882 #define CH_MIN(c) (c[0] < c[1] ? (c[0] < c[2] ? c[0] : c[2]) : (c[1] < c[2] ? c[1] : c[2]))
883 #define CH_MAX(c) (c[0] > c[1] ? (c[0] > c[2] ? c[0] : c[2]) : (c[1] > c[2] ? c[1] : c[2]))
884 #define LUM(c) ((c[0] * 30 + c[1] * 59 + c[2] * 11) / 100)
885 #define SAT(c) (CH_MAX (c) - CH_MIN (c))
887 #define PDF_NON_SEPARABLE_BLEND_MODE(name) \
889 combine_ ## name ## _u (pixman_implementation_t *imp, \
892 const comp4_t *src, \
893 const comp4_t *mask, \
897 for (i = 0; i < width; ++i) \
899 comp4_t s = combine_mask (src, mask, i); \
900 comp4_t d = *(dest + i); \
901 comp1_t sa = ALPHA_c (s); \
903 comp1_t da = ALPHA_c (d); \
906 comp4_t sc[3], dc[3], c[3]; \
909 UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida); \
912 dc[1] = GREEN_c (d); \
913 sc[1] = GREEN_c (s); \
914 dc[2] = BLUE_c (d); \
915 sc[2] = BLUE_c (s); \
916 blend_ ## name (c, dc, da, sc, sa); \
918 *(dest + i) = result + \
919 (DIV_ONE_UNc (sa * da) << A_SHIFT) + \
920 (DIV_ONE_UNc (c[0]) << R_SHIFT) + \
921 (DIV_ONE_UNc (c[1]) << G_SHIFT) + \
922 (DIV_ONE_UNc (c[2])); \
927 set_lum (comp4_t dest[3], comp4_t src[3], comp4_t sa, comp4_t lum)
929 double a, l, min, max;
932 a = sa * (1.0 / MASK);
934 l = lum * (1.0 / MASK);
935 tmp[0] = src[0] * (1.0 / MASK);
936 tmp[1] = src[1] * (1.0 / MASK);
937 tmp[2] = src[2] * (1.0 / MASK);
951 tmp[0] = l + (tmp[0] - l) * l / (l - min);
952 tmp[1] = l + (tmp[1] - l) * l / (l - min);
953 tmp[2] = l + (tmp[2] - l) * l / (l - min);
957 tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l);
958 tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l);
959 tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l);
962 dest[0] = tmp[0] * MASK + 0.5;
963 dest[1] = tmp[1] * MASK + 0.5;
964 dest[2] = tmp[2] * MASK + 0.5;
968 set_sat (comp4_t dest[3], comp4_t src[3], comp4_t sat)
1007 if (src[1] > src[2])
1024 dest[id[1]] = (dest[id[1]] - min) * sat / (max - min);
1030 dest[0] = dest[1] = dest[2] = 0;
1036 * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb))
1039 blend_hsl_hue (comp4_t c[3],
1048 set_sat (c, c, SAT (dc) * sa);
1049 set_lum (c, c, sa * da, LUM (dc) * sa);
1052 PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue)
1056 * B(Cb, Cs) = set_lum (set_sat (Cb, SAT (Cs)), LUM (Cb))
1059 blend_hsl_saturation (comp4_t c[3],
1068 set_sat (c, c, SAT (sc) * da);
1069 set_lum (c, c, sa * da, LUM (dc) * sa);
1072 PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation)
1076 * B(Cb, Cs) = set_lum (Cs, LUM (Cb))
1079 blend_hsl_color (comp4_t c[3],
1088 set_lum (c, c, sa * da, LUM (dc) * sa);
1091 PDF_NON_SEPARABLE_BLEND_MODE (hsl_color)
1095 * B(Cb, Cs) = set_lum (Cb, LUM (Cs))
1098 blend_hsl_luminosity (comp4_t c[3],
1107 set_lum (c, c, sa * da, LUM (sc) * da);
1110 PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
1116 #undef PDF_NON_SEPARABLE_BLEND_MODE
1120 * All of the disjoint composing functions
1122 * The four entries in the first column indicate what source contributions
1123 * come from each of the four areas of the picture -- areas covered by neither
1124 * A nor B, areas covered only by A, areas covered only by B and finally
1125 * areas covered by both A and B.
1132 * (0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0)
1133 * (0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1
1134 * (0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0
1135 * (0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1)
1136 * (0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0
1137 * (0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0)
1138 * (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0)
1139 * (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b)
1140 * (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0)
1143 #define COMBINE_A_OUT 1
1144 #define COMBINE_A_IN 2
1145 #define COMBINE_B_OUT 4
1146 #define COMBINE_B_IN 8
1148 #define COMBINE_CLEAR 0
1149 #define COMBINE_A (COMBINE_A_OUT | COMBINE_A_IN)
1150 #define COMBINE_B (COMBINE_B_OUT | COMBINE_B_IN)
1151 #define COMBINE_A_OVER (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_A_IN)
1152 #define COMBINE_B_OVER (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_B_IN)
1153 #define COMBINE_A_ATOP (COMBINE_B_OUT | COMBINE_A_IN)
1154 #define COMBINE_B_ATOP (COMBINE_A_OUT | COMBINE_B_IN)
1155 #define COMBINE_XOR (COMBINE_A_OUT | COMBINE_B_OUT)
1157 /* portion covered by a but not b */
1159 combine_disjoint_out_part (comp1_t a, comp1_t b)
1161 /* min (1, (1-b) / a) */
1164 if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
1165 return MASK; /* 1 */
1166 return DIV_UNc (b, a); /* (1-b) / a */
1169 /* portion covered by both a and b */
1171 combine_disjoint_in_part (comp1_t a, comp1_t b)
1173 /* max (1-(1-b)/a,0) */
1174 /* = - min ((1-b)/a - 1, 0) */
1175 /* = 1 - min (1, (1-b)/a) */
1178 if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
1179 return 0; /* 1 - 1 */
1180 return ~DIV_UNc(b, a); /* 1 - (1-b) / a */
1183 /* portion covered by a but not b */
1185 combine_conjoint_out_part (comp1_t a, comp1_t b)
1188 /* = 1-min(b/a,1) */
1190 /* min (1, (1-b) / a) */
1192 if (b >= a) /* b >= a -> b/a >= 1 */
1193 return 0x00; /* 0 */
1194 return ~DIV_UNc(b, a); /* 1 - b/a */
1197 /* portion covered by both a and b */
1199 combine_conjoint_in_part (comp1_t a, comp1_t b)
1203 if (b >= a) /* b >= a -> b/a >= 1 */
1204 return MASK; /* 1 */
1205 return DIV_UNc (b, a); /* b/a */
1208 #define GET_COMP(v, i) ((comp2_t) (comp1_t) ((v) >> i))
1210 #define ADD(x, y, i, t) \
1211 ((t) = GET_COMP (x, i) + GET_COMP (y, i), \
1212 (comp4_t) ((comp1_t) ((t) | (0 - ((t) >> G_SHIFT)))) << (i))
1214 #define GENERIC(x, y, i, ax, ay, t, u, v) \
1215 ((t) = (MUL_UNc (GET_COMP (y, i), ay, (u)) + \
1216 MUL_UNc (GET_COMP (x, i), ax, (v))), \
1217 (comp4_t) ((comp1_t) ((t) | \
1218 (0 - ((t) >> G_SHIFT)))) << (i))
1221 combine_disjoint_general_u (comp4_t * dest,
1223 const comp4_t *mask,
1229 for (i = 0; i < width; ++i)
1231 comp4_t s = combine_mask (src, mask, i);
1232 comp4_t d = *(dest + i);
1234 comp2_t Fa, Fb, t, u, v;
1235 comp1_t sa = s >> A_SHIFT;
1236 comp1_t da = d >> A_SHIFT;
1238 switch (combine & COMBINE_A)
1245 Fa = combine_disjoint_out_part (sa, da);
1249 Fa = combine_disjoint_in_part (sa, da);
1257 switch (combine & COMBINE_B)
1264 Fb = combine_disjoint_out_part (da, sa);
1268 Fb = combine_disjoint_in_part (da, sa);
1275 m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
1276 n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
1277 o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
1278 p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
1285 combine_disjoint_over_u (pixman_implementation_t *imp,
1288 const comp4_t * src,
1289 const comp4_t * mask,
1294 for (i = 0; i < width; ++i)
1296 comp4_t s = combine_mask (src, mask, i);
1297 comp2_t a = s >> A_SHIFT;
1303 comp4_t d = *(dest + i);
1304 a = combine_disjoint_out_part (d >> A_SHIFT, a);
1305 UNcx4_MUL_UNc_ADD_UNcx4 (d, a, s);
1315 combine_disjoint_in_u (pixman_implementation_t *imp,
1318 const comp4_t * src,
1319 const comp4_t * mask,
1322 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
1326 combine_disjoint_in_reverse_u (pixman_implementation_t *imp,
1329 const comp4_t * src,
1330 const comp4_t * mask,
1333 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
1337 combine_disjoint_out_u (pixman_implementation_t *imp,
1340 const comp4_t * src,
1341 const comp4_t * mask,
1344 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
1348 combine_disjoint_out_reverse_u (pixman_implementation_t *imp,
1351 const comp4_t * src,
1352 const comp4_t * mask,
1355 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
1359 combine_disjoint_atop_u (pixman_implementation_t *imp,
1362 const comp4_t * src,
1363 const comp4_t * mask,
1366 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
1370 combine_disjoint_atop_reverse_u (pixman_implementation_t *imp,
1373 const comp4_t * src,
1374 const comp4_t * mask,
1377 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
1381 combine_disjoint_xor_u (pixman_implementation_t *imp,
1384 const comp4_t * src,
1385 const comp4_t * mask,
1388 combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR);
1392 combine_conjoint_general_u (comp4_t * dest,
1394 const comp4_t *mask,
1400 for (i = 0; i < width; ++i)
1402 comp4_t s = combine_mask (src, mask, i);
1403 comp4_t d = *(dest + i);
1405 comp2_t Fa, Fb, t, u, v;
1406 comp1_t sa = s >> A_SHIFT;
1407 comp1_t da = d >> A_SHIFT;
1409 switch (combine & COMBINE_A)
1416 Fa = combine_conjoint_out_part (sa, da);
1420 Fa = combine_conjoint_in_part (sa, da);
1428 switch (combine & COMBINE_B)
1435 Fb = combine_conjoint_out_part (da, sa);
1439 Fb = combine_conjoint_in_part (da, sa);
1447 m = GENERIC (s, d, 0, Fa, Fb, t, u, v);
1448 n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v);
1449 o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v);
1450 p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v);
1459 combine_conjoint_over_u (pixman_implementation_t *imp,
1462 const comp4_t * src,
1463 const comp4_t * mask,
1466 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER);
1470 combine_conjoint_over_reverse_u (pixman_implementation_t *imp,
1473 const comp4_t * src,
1474 const comp4_t * mask,
1477 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER);
1481 combine_conjoint_in_u (pixman_implementation_t *imp,
1484 const comp4_t * src,
1485 const comp4_t * mask,
1488 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN);
1492 combine_conjoint_in_reverse_u (pixman_implementation_t *imp,
1495 const comp4_t * src,
1496 const comp4_t * mask,
1499 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN);
1503 combine_conjoint_out_u (pixman_implementation_t *imp,
1506 const comp4_t * src,
1507 const comp4_t * mask,
1510 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT);
1514 combine_conjoint_out_reverse_u (pixman_implementation_t *imp,
1517 const comp4_t * src,
1518 const comp4_t * mask,
1521 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT);
1525 combine_conjoint_atop_u (pixman_implementation_t *imp,
1528 const comp4_t * src,
1529 const comp4_t * mask,
1532 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP);
1536 combine_conjoint_atop_reverse_u (pixman_implementation_t *imp,
1539 const comp4_t * src,
1540 const comp4_t * mask,
1543 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP);
1547 combine_conjoint_xor_u (pixman_implementation_t *imp,
1550 const comp4_t * src,
1551 const comp4_t * mask,
1554 combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR);
1557 /************************************************************************/
1558 /*********************** Per Channel functions **************************/
1559 /************************************************************************/
1562 combine_clear_ca (pixman_implementation_t *imp,
1565 const comp4_t * src,
1566 const comp4_t * mask,
1569 memset (dest, 0, width * sizeof(comp4_t));
1573 combine_src_ca (pixman_implementation_t *imp,
1576 const comp4_t * src,
1577 const comp4_t * mask,
1582 for (i = 0; i < width; ++i)
1584 comp4_t s = *(src + i);
1585 comp4_t m = *(mask + i);
1587 combine_mask_value_ca (&s, &m);
1594 combine_over_ca (pixman_implementation_t *imp,
1597 const comp4_t * src,
1598 const comp4_t * mask,
1603 for (i = 0; i < width; ++i)
1605 comp4_t s = *(src + i);
1606 comp4_t m = *(mask + i);
1609 combine_mask_ca (&s, &m);
1616 comp4_t d = *(dest + i);
1617 UNcx4_MUL_UNcx4_ADD_UNcx4 (d, a, s);
1627 combine_over_reverse_ca (pixman_implementation_t *imp,
1630 const comp4_t * src,
1631 const comp4_t * mask,
1636 for (i = 0; i < width; ++i)
1638 comp4_t d = *(dest + i);
1639 comp4_t a = ~d >> A_SHIFT;
1643 comp4_t s = *(src + i);
1644 comp4_t m = *(mask + i);
1646 combine_mask_value_ca (&s, &m);
1649 UNcx4_MUL_UNc_ADD_UNcx4 (s, a, d);
1657 combine_in_ca (pixman_implementation_t *imp,
1660 const comp4_t * src,
1661 const comp4_t * mask,
1666 for (i = 0; i < width; ++i)
1668 comp4_t d = *(dest + i);
1669 comp2_t a = d >> A_SHIFT;
1674 comp4_t m = *(mask + i);
1677 combine_mask_value_ca (&s, &m);
1680 UNcx4_MUL_UNc (s, a);
1688 combine_in_reverse_ca (pixman_implementation_t *imp,
1691 const comp4_t * src,
1692 const comp4_t * mask,
1697 for (i = 0; i < width; ++i)
1699 comp4_t s = *(src + i);
1700 comp4_t m = *(mask + i);
1703 combine_mask_alpha_ca (&s, &m);
1713 UNcx4_MUL_UNcx4 (d, a);
1722 combine_out_ca (pixman_implementation_t *imp,
1725 const comp4_t * src,
1726 const comp4_t * mask,
1731 for (i = 0; i < width; ++i)
1733 comp4_t d = *(dest + i);
1734 comp2_t a = ~d >> A_SHIFT;
1739 comp4_t m = *(mask + i);
1742 combine_mask_value_ca (&s, &m);
1745 UNcx4_MUL_UNc (s, a);
1753 combine_out_reverse_ca (pixman_implementation_t *imp,
1756 const comp4_t * src,
1757 const comp4_t * mask,
1762 for (i = 0; i < width; ++i)
1764 comp4_t s = *(src + i);
1765 comp4_t m = *(mask + i);
1768 combine_mask_alpha_ca (&s, &m);
1778 UNcx4_MUL_UNcx4 (d, a);
1787 combine_atop_ca (pixman_implementation_t *imp,
1790 const comp4_t * src,
1791 const comp4_t * mask,
1796 for (i = 0; i < width; ++i)
1798 comp4_t d = *(dest + i);
1799 comp4_t s = *(src + i);
1800 comp4_t m = *(mask + i);
1802 comp2_t as = d >> A_SHIFT;
1804 combine_mask_ca (&s, &m);
1808 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (d, ad, s, as);
1815 combine_atop_reverse_ca (pixman_implementation_t *imp,
1818 const comp4_t * src,
1819 const comp4_t * mask,
1824 for (i = 0; i < width; ++i)
1826 comp4_t d = *(dest + i);
1827 comp4_t s = *(src + i);
1828 comp4_t m = *(mask + i);
1830 comp2_t as = ~d >> A_SHIFT;
1832 combine_mask_ca (&s, &m);
1836 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (d, ad, s, as);
1843 combine_xor_ca (pixman_implementation_t *imp,
1846 const comp4_t * src,
1847 const comp4_t * mask,
1852 for (i = 0; i < width; ++i)
1854 comp4_t d = *(dest + i);
1855 comp4_t s = *(src + i);
1856 comp4_t m = *(mask + i);
1858 comp2_t as = ~d >> A_SHIFT;
1860 combine_mask_ca (&s, &m);
1864 UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (d, ad, s, as);
1871 combine_add_ca (pixman_implementation_t *imp,
1874 const comp4_t * src,
1875 const comp4_t * mask,
1880 for (i = 0; i < width; ++i)
1882 comp4_t s = *(src + i);
1883 comp4_t m = *(mask + i);
1884 comp4_t d = *(dest + i);
1886 combine_mask_value_ca (&s, &m);
1888 UNcx4_ADD_UNcx4 (d, s);
1895 combine_saturate_ca (pixman_implementation_t *imp,
1898 const comp4_t * src,
1899 const comp4_t * mask,
1904 for (i = 0; i < width; ++i)
1907 comp2_t sa, sr, sg, sb, da;
1915 combine_mask_ca (&s, &m);
1917 sa = (m >> A_SHIFT);
1918 sr = (m >> R_SHIFT) & MASK;
1919 sg = (m >> G_SHIFT) & MASK;
1924 m = ADD (s, d, 0, t);
1926 m = GENERIC (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v);
1929 n = ADD (s, d, G_SHIFT, t);
1931 n = GENERIC (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v);
1934 o = ADD (s, d, R_SHIFT, t);
1936 o = GENERIC (s, d, R_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v);
1939 p = ADD (s, d, A_SHIFT, t);
1941 p = GENERIC (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v);
1943 *(dest + i) = m | n | o | p;
1948 combine_disjoint_general_ca (comp4_t * dest,
1950 const comp4_t *mask,
1956 for (i = 0; i < width; ++i)
1970 combine_mask_ca (&s, &m);
1974 switch (combine & COMBINE_A)
1981 m = (comp4_t)combine_disjoint_out_part ((comp1_t) (sa >> 0), da);
1982 n = (comp4_t)combine_disjoint_out_part ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT;
1983 o = (comp4_t)combine_disjoint_out_part ((comp1_t) (sa >> R_SHIFT), da) << R_SHIFT;
1984 p = (comp4_t)combine_disjoint_out_part ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT;
1989 m = (comp4_t)combine_disjoint_in_part ((comp1_t) (sa >> 0), da);
1990 n = (comp4_t)combine_disjoint_in_part ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT;
1991 o = (comp4_t)combine_disjoint_in_part ((comp1_t) (sa >> R_SHIFT), da) << R_SHIFT;
1992 p = (comp4_t)combine_disjoint_in_part ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT;
2001 switch (combine & COMBINE_B)
2008 m = (comp4_t)combine_disjoint_out_part (da, (comp1_t) (sa >> 0));
2009 n = (comp4_t)combine_disjoint_out_part (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT;
2010 o = (comp4_t)combine_disjoint_out_part (da, (comp1_t) (sa >> R_SHIFT)) << R_SHIFT;
2011 p = (comp4_t)combine_disjoint_out_part (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT;
2016 m = (comp4_t)combine_disjoint_in_part (da, (comp1_t) (sa >> 0));
2017 n = (comp4_t)combine_disjoint_in_part (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT;
2018 o = (comp4_t)combine_disjoint_in_part (da, (comp1_t) (sa >> R_SHIFT)) << R_SHIFT;
2019 p = (comp4_t)combine_disjoint_in_part (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT;
2027 m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
2028 n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
2029 o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
2030 p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
2039 combine_disjoint_over_ca (pixman_implementation_t *imp,
2042 const comp4_t * src,
2043 const comp4_t * mask,
2046 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
2050 combine_disjoint_in_ca (pixman_implementation_t *imp,
2053 const comp4_t * src,
2054 const comp4_t * mask,
2057 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
2061 combine_disjoint_in_reverse_ca (pixman_implementation_t *imp,
2064 const comp4_t * src,
2065 const comp4_t * mask,
2068 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
2072 combine_disjoint_out_ca (pixman_implementation_t *imp,
2075 const comp4_t * src,
2076 const comp4_t * mask,
2079 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
2083 combine_disjoint_out_reverse_ca (pixman_implementation_t *imp,
2086 const comp4_t * src,
2087 const comp4_t * mask,
2090 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
2094 combine_disjoint_atop_ca (pixman_implementation_t *imp,
2097 const comp4_t * src,
2098 const comp4_t * mask,
2101 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
2105 combine_disjoint_atop_reverse_ca (pixman_implementation_t *imp,
2108 const comp4_t * src,
2109 const comp4_t * mask,
2112 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
2116 combine_disjoint_xor_ca (pixman_implementation_t *imp,
2119 const comp4_t * src,
2120 const comp4_t * mask,
2123 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
2127 combine_conjoint_general_ca (comp4_t * dest,
2129 const comp4_t *mask,
2135 for (i = 0; i < width; ++i)
2149 combine_mask_ca (&s, &m);
2153 switch (combine & COMBINE_A)
2160 m = (comp4_t)combine_conjoint_out_part ((comp1_t) (sa >> 0), da);
2161 n = (comp4_t)combine_conjoint_out_part ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT;
2162 o = (comp4_t)combine_conjoint_out_part ((comp1_t) (sa >> R_SHIFT), da) << R_SHIFT;
2163 p = (comp4_t)combine_conjoint_out_part ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT;
2168 m = (comp4_t)combine_conjoint_in_part ((comp1_t) (sa >> 0), da);
2169 n = (comp4_t)combine_conjoint_in_part ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT;
2170 o = (comp4_t)combine_conjoint_in_part ((comp1_t) (sa >> R_SHIFT), da) << R_SHIFT;
2171 p = (comp4_t)combine_conjoint_in_part ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT;
2180 switch (combine & COMBINE_B)
2187 m = (comp4_t)combine_conjoint_out_part (da, (comp1_t) (sa >> 0));
2188 n = (comp4_t)combine_conjoint_out_part (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT;
2189 o = (comp4_t)combine_conjoint_out_part (da, (comp1_t) (sa >> R_SHIFT)) << R_SHIFT;
2190 p = (comp4_t)combine_conjoint_out_part (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT;
2195 m = (comp4_t)combine_conjoint_in_part (da, (comp1_t) (sa >> 0));
2196 n = (comp4_t)combine_conjoint_in_part (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT;
2197 o = (comp4_t)combine_conjoint_in_part (da, (comp1_t) (sa >> R_SHIFT)) << R_SHIFT;
2198 p = (comp4_t)combine_conjoint_in_part (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT;
2206 m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v);
2207 n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v);
2208 o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v);
2209 p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v);
2218 combine_conjoint_over_ca (pixman_implementation_t *imp,
2221 const comp4_t * src,
2222 const comp4_t * mask,
2225 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER);
2229 combine_conjoint_over_reverse_ca (pixman_implementation_t *imp,
2232 const comp4_t * src,
2233 const comp4_t * mask,
2236 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER);
2240 combine_conjoint_in_ca (pixman_implementation_t *imp,
2243 const comp4_t * src,
2244 const comp4_t * mask,
2247 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN);
2251 combine_conjoint_in_reverse_ca (pixman_implementation_t *imp,
2254 const comp4_t * src,
2255 const comp4_t * mask,
2258 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN);
2262 combine_conjoint_out_ca (pixman_implementation_t *imp,
2265 const comp4_t * src,
2266 const comp4_t * mask,
2269 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT);
2273 combine_conjoint_out_reverse_ca (pixman_implementation_t *imp,
2276 const comp4_t * src,
2277 const comp4_t * mask,
2280 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT);
2284 combine_conjoint_atop_ca (pixman_implementation_t *imp,
2287 const comp4_t * src,
2288 const comp4_t * mask,
2291 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP);
2295 combine_conjoint_atop_reverse_ca (pixman_implementation_t *imp,
2298 const comp4_t * src,
2299 const comp4_t * mask,
2302 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP);
2306 combine_conjoint_xor_ca (pixman_implementation_t *imp,
2309 const comp4_t * src,
2310 const comp4_t * mask,
2313 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR);
2317 _pixman_setup_combiner_functions_width (pixman_implementation_t *imp)
2320 imp->combine_width[PIXMAN_OP_CLEAR] = combine_clear;
2321 imp->combine_width[PIXMAN_OP_SRC] = combine_src_u;
2323 imp->combine_width[PIXMAN_OP_OVER] = combine_over_u;
2324 imp->combine_width[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_u;
2325 imp->combine_width[PIXMAN_OP_IN] = combine_in_u;
2326 imp->combine_width[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_u;
2327 imp->combine_width[PIXMAN_OP_OUT] = combine_out_u;
2328 imp->combine_width[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_u;
2329 imp->combine_width[PIXMAN_OP_ATOP] = combine_atop_u;
2330 imp->combine_width[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u;
2331 imp->combine_width[PIXMAN_OP_XOR] = combine_xor_u;
2332 imp->combine_width[PIXMAN_OP_ADD] = combine_add_u;
2333 imp->combine_width[PIXMAN_OP_SATURATE] = combine_saturate_u;
2335 /* Disjoint, unified */
2336 imp->combine_width[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear;
2337 imp->combine_width[PIXMAN_OP_DISJOINT_SRC] = combine_src_u;
2339 imp->combine_width[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u;
2340 imp->combine_width[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_u;
2341 imp->combine_width[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u;
2342 imp->combine_width[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_u;
2343 imp->combine_width[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_u;
2344 imp->combine_width[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_u;
2345 imp->combine_width[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_u;
2346 imp->combine_width[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_u;
2347 imp->combine_width[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_u;
2349 /* Conjoint, unified */
2350 imp->combine_width[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear;
2351 imp->combine_width[PIXMAN_OP_CONJOINT_SRC] = combine_src_u;
2353 imp->combine_width[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u;
2354 imp->combine_width[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_u;
2355 imp->combine_width[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u;
2356 imp->combine_width[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_u;
2357 imp->combine_width[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_u;
2358 imp->combine_width[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_u;
2359 imp->combine_width[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_u;
2360 imp->combine_width[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_u;
2361 imp->combine_width[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_u;
2363 imp->combine_width[PIXMAN_OP_MULTIPLY] = combine_multiply_u;
2364 imp->combine_width[PIXMAN_OP_SCREEN] = combine_screen_u;
2365 imp->combine_width[PIXMAN_OP_OVERLAY] = combine_overlay_u;
2366 imp->combine_width[PIXMAN_OP_DARKEN] = combine_darken_u;
2367 imp->combine_width[PIXMAN_OP_LIGHTEN] = combine_lighten_u;
2368 imp->combine_width[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_u;
2369 imp->combine_width[PIXMAN_OP_COLOR_BURN] = combine_color_burn_u;
2370 imp->combine_width[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u;
2371 imp->combine_width[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_u;
2372 imp->combine_width[PIXMAN_OP_DIFFERENCE] = combine_difference_u;
2373 imp->combine_width[PIXMAN_OP_EXCLUSION] = combine_exclusion_u;
2374 imp->combine_width[PIXMAN_OP_HSL_HUE] = combine_hsl_hue_u;
2375 imp->combine_width[PIXMAN_OP_HSL_SATURATION] = combine_hsl_saturation_u;
2376 imp->combine_width[PIXMAN_OP_HSL_COLOR] = combine_hsl_color_u;
2377 imp->combine_width[PIXMAN_OP_HSL_LUMINOSITY] = combine_hsl_luminosity_u;
2379 /* Component alpha combiners */
2380 imp->combine_width_ca[PIXMAN_OP_CLEAR] = combine_clear_ca;
2381 imp->combine_width_ca[PIXMAN_OP_SRC] = combine_src_ca;
2383 imp->combine_width_ca[PIXMAN_OP_OVER] = combine_over_ca;
2384 imp->combine_width_ca[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_ca;
2385 imp->combine_width_ca[PIXMAN_OP_IN] = combine_in_ca;
2386 imp->combine_width_ca[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_ca;
2387 imp->combine_width_ca[PIXMAN_OP_OUT] = combine_out_ca;
2388 imp->combine_width_ca[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_ca;
2389 imp->combine_width_ca[PIXMAN_OP_ATOP] = combine_atop_ca;
2390 imp->combine_width_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca;
2391 imp->combine_width_ca[PIXMAN_OP_XOR] = combine_xor_ca;
2392 imp->combine_width_ca[PIXMAN_OP_ADD] = combine_add_ca;
2393 imp->combine_width_ca[PIXMAN_OP_SATURATE] = combine_saturate_ca;
2396 imp->combine_width_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear_ca;
2397 imp->combine_width_ca[PIXMAN_OP_DISJOINT_SRC] = combine_src_ca;
2399 imp->combine_width_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca;
2400 imp->combine_width_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_ca;
2401 imp->combine_width_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca;
2402 imp->combine_width_ca[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_ca;
2403 imp->combine_width_ca[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_ca;
2404 imp->combine_width_ca[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_ca;
2405 imp->combine_width_ca[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_ca;
2406 imp->combine_width_ca[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_ca;
2407 imp->combine_width_ca[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_ca;
2410 imp->combine_width_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear_ca;
2411 imp->combine_width_ca[PIXMAN_OP_CONJOINT_SRC] = combine_src_ca;
2413 imp->combine_width_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca;
2414 imp->combine_width_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_ca;
2415 imp->combine_width_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca;
2416 imp->combine_width_ca[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_ca;
2417 imp->combine_width_ca[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_ca;
2418 imp->combine_width_ca[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_ca;
2419 imp->combine_width_ca[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_ca;
2420 imp->combine_width_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_ca;
2421 imp->combine_width_ca[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_ca;
2423 imp->combine_width_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca;
2424 imp->combine_width_ca[PIXMAN_OP_SCREEN] = combine_screen_ca;
2425 imp->combine_width_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca;
2426 imp->combine_width_ca[PIXMAN_OP_DARKEN] = combine_darken_ca;
2427 imp->combine_width_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca;
2428 imp->combine_width_ca[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_ca;
2429 imp->combine_width_ca[PIXMAN_OP_COLOR_BURN] = combine_color_burn_ca;
2430 imp->combine_width_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca;
2431 imp->combine_width_ca[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_ca;
2432 imp->combine_width_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca;
2433 imp->combine_width_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca;
2435 /* It is not clear that these make sense, so leave them out for now */
2436 imp->combine_width_ca[PIXMAN_OP_HSL_HUE] = NULL;
2437 imp->combine_width_ca[PIXMAN_OP_HSL_SATURATION] = NULL;
2438 imp->combine_width_ca[PIXMAN_OP_HSL_COLOR] = NULL;
2439 imp->combine_width_ca[PIXMAN_OP_HSL_LUMINOSITY] = NULL;