Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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
  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
  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.  
  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.  
  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.  
  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.  
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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.