Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
  2. /*
  3.  * Copyright © 2000 SuSE, Inc.
  4.  * Copyright © 2007 Red Hat, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of SuSE not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  SuSE makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Keith Packard, SuSE, Inc.
  24.  */
  25.  
  26. #ifdef HAVE_CONFIG_H
  27. #include <config.h>
  28. #endif
  29. #include "pixman-private.h"
  30.  
  31. #include <stdlib.h>
  32.  
  33. pixman_implementation_t *global_implementation;
  34.  
  35. #ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
  36. static void __attribute__((constructor))
  37. pixman_constructor (void)
  38. {
  39.     global_implementation = _pixman_choose_implementation ();
  40. }
  41. #endif
  42.  
  43. typedef struct operator_info_t operator_info_t;
  44.  
  45. struct operator_info_t
  46. {
  47.     uint8_t     opaque_info[4];
  48. };
  49.  
  50. #define PACK(neither, src, dest, both)                  \
  51.     {{      (uint8_t)PIXMAN_OP_ ## neither,             \
  52.             (uint8_t)PIXMAN_OP_ ## src,                 \
  53.             (uint8_t)PIXMAN_OP_ ## dest,                \
  54.             (uint8_t)PIXMAN_OP_ ## both         }}
  55.  
  56. static const operator_info_t operator_table[] =
  57. {
  58.     /*    Neither Opaque         Src Opaque             Dst Opaque             Both Opaque */
  59.     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
  60.     PACK (SRC,                   SRC,                   SRC,                   SRC),
  61.     PACK (DST,                   DST,                   DST,                   DST),
  62.     PACK (OVER,                  SRC,                   OVER,                  SRC),
  63.     PACK (OVER_REVERSE,          OVER_REVERSE,          DST,                   DST),
  64.     PACK (IN,                    IN,                    SRC,                   SRC),
  65.     PACK (IN_REVERSE,            DST,                   IN_REVERSE,            DST),
  66.     PACK (OUT,                   OUT,                   CLEAR,                 CLEAR),
  67.     PACK (OUT_REVERSE,           CLEAR,                 OUT_REVERSE,           CLEAR),
  68.     PACK (ATOP,                  IN,                    OVER,                  SRC),
  69.     PACK (ATOP_REVERSE,          OVER_REVERSE,          IN_REVERSE,            DST),
  70.     PACK (XOR,                   OUT,                   OUT_REVERSE,           CLEAR),
  71.     PACK (ADD,                   ADD,                   ADD,                   ADD),
  72.     PACK (SATURATE,              OVER_REVERSE,          DST,                   DST),
  73.  
  74.     {{ 0 /* 0x0e */ }},
  75.     {{ 0 /* 0x0f */ }},
  76.  
  77.     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
  78.     PACK (SRC,                   SRC,                   SRC,                   SRC),
  79.     PACK (DST,                   DST,                   DST,                   DST),
  80.     PACK (DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER,         DISJOINT_OVER),
  81.     PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
  82.     PACK (DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN,           DISJOINT_IN),
  83.     PACK (DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE,   DISJOINT_IN_REVERSE),
  84.     PACK (DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT,          DISJOINT_OUT),
  85.     PACK (DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE,  DISJOINT_OUT_REVERSE),
  86.     PACK (DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP,         DISJOINT_ATOP),
  87.     PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
  88.     PACK (DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR,          DISJOINT_XOR),
  89.  
  90.     {{ 0 /* 0x1c */ }},
  91.     {{ 0 /* 0x1d */ }},
  92.     {{ 0 /* 0x1e */ }},
  93.     {{ 0 /* 0x1f */ }},
  94.  
  95.     PACK (CLEAR,                 CLEAR,                 CLEAR,                 CLEAR),
  96.     PACK (SRC,                   SRC,                   SRC,                   SRC),
  97.     PACK (DST,                   DST,                   DST,                   DST),
  98.     PACK (CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER,         CONJOINT_OVER),
  99.     PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
  100.     PACK (CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN,           CONJOINT_IN),
  101.     PACK (CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE,   CONJOINT_IN_REVERSE),
  102.     PACK (CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT,          CONJOINT_OUT),
  103.     PACK (CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE,  CONJOINT_OUT_REVERSE),
  104.     PACK (CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP,         CONJOINT_ATOP),
  105.     PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
  106.     PACK (CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR,          CONJOINT_XOR),
  107.  
  108.     {{ 0 /* 0x2c */ }},
  109.     {{ 0 /* 0x2d */ }},
  110.     {{ 0 /* 0x2e */ }},
  111.     {{ 0 /* 0x2f */ }},
  112.  
  113.     PACK (MULTIPLY,              MULTIPLY,              MULTIPLY,              MULTIPLY),
  114.     PACK (SCREEN,                SCREEN,                SCREEN,                SCREEN),
  115.     PACK (OVERLAY,               OVERLAY,               OVERLAY,               OVERLAY),
  116.     PACK (DARKEN,                DARKEN,                DARKEN,                DARKEN),
  117.     PACK (LIGHTEN,               LIGHTEN,               LIGHTEN,               LIGHTEN),
  118.     PACK (COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE,           COLOR_DODGE),
  119.     PACK (COLOR_BURN,            COLOR_BURN,            COLOR_BURN,            COLOR_BURN),
  120.     PACK (HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT,            HARD_LIGHT),
  121.     PACK (SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT,            SOFT_LIGHT),
  122.     PACK (DIFFERENCE,            DIFFERENCE,            DIFFERENCE,            DIFFERENCE),
  123.     PACK (EXCLUSION,             EXCLUSION,             EXCLUSION,             EXCLUSION),
  124.     PACK (HSL_HUE,               HSL_HUE,               HSL_HUE,               HSL_HUE),
  125.     PACK (HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION,        HSL_SATURATION),
  126.     PACK (HSL_COLOR,             HSL_COLOR,             HSL_COLOR,             HSL_COLOR),
  127.     PACK (HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY,        HSL_LUMINOSITY),
  128. };
  129.  
  130. /*
  131.  * Optimize the current operator based on opacity of source or destination
  132.  * The output operator should be mathematically equivalent to the source.
  133.  */
  134. static pixman_op_t
  135. optimize_operator (pixman_op_t     op,
  136.                    uint32_t        src_flags,
  137.                    uint32_t        mask_flags,
  138.                    uint32_t        dst_flags)
  139. {
  140.     pixman_bool_t is_source_opaque, is_dest_opaque;
  141.  
  142. #define OPAQUE_SHIFT 13
  143.    
  144.     COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
  145.    
  146.     is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
  147.     is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
  148.  
  149.     is_dest_opaque >>= OPAQUE_SHIFT - 1;
  150.     is_source_opaque >>= OPAQUE_SHIFT;
  151.  
  152.     return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
  153. }
  154.  
  155. /*
  156.  * Computing composite region
  157.  */
  158. static inline pixman_bool_t
  159. clip_general_image (pixman_region32_t * region,
  160.                     pixman_region32_t * clip,
  161.                     int                 dx,
  162.                     int                 dy)
  163. {
  164.     if (pixman_region32_n_rects (region) == 1 &&
  165.         pixman_region32_n_rects (clip) == 1)
  166.     {
  167.         pixman_box32_t *  rbox = pixman_region32_rectangles (region, NULL);
  168.         pixman_box32_t *  cbox = pixman_region32_rectangles (clip, NULL);
  169.         int v;
  170.  
  171.         if (rbox->x1 < (v = cbox->x1 + dx))
  172.             rbox->x1 = v;
  173.         if (rbox->x2 > (v = cbox->x2 + dx))
  174.             rbox->x2 = v;
  175.         if (rbox->y1 < (v = cbox->y1 + dy))
  176.             rbox->y1 = v;
  177.         if (rbox->y2 > (v = cbox->y2 + dy))
  178.             rbox->y2 = v;
  179.         if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
  180.         {
  181.             pixman_region32_init (region);
  182.             return FALSE;
  183.         }
  184.     }
  185.     else if (!pixman_region32_not_empty (clip))
  186.     {
  187.         return FALSE;
  188.     }
  189.     else
  190.     {
  191.         if (dx || dy)
  192.             pixman_region32_translate (region, -dx, -dy);
  193.  
  194.         if (!pixman_region32_intersect (region, region, clip))
  195.             return FALSE;
  196.  
  197.         if (dx || dy)
  198.             pixman_region32_translate (region, dx, dy);
  199.     }
  200.  
  201.     return pixman_region32_not_empty (region);
  202. }
  203.  
  204. static inline pixman_bool_t
  205. clip_source_image (pixman_region32_t * region,
  206.                    pixman_image_t *    image,
  207.                    int                 dx,
  208.                    int                 dy)
  209. {
  210.     /* Source clips are ignored, unless they are explicitly turned on
  211.      * and the clip in question was set by an X client. (Because if
  212.      * the clip was not set by a client, then it is a hierarchy
  213.      * clip and those should always be ignored for sources).
  214.      */
  215.     if (!image->common.clip_sources || !image->common.client_clip)
  216.         return TRUE;
  217.  
  218.     return clip_general_image (region,
  219.                                &image->common.clip_region,
  220.                                dx, dy);
  221. }
  222.  
  223. /*
  224.  * returns FALSE if the final region is empty.  Indistinguishable from
  225.  * an allocation failure, but rendering ignores those anyways.
  226.  */
  227. pixman_bool_t
  228. _pixman_compute_composite_region32 (pixman_region32_t * region,
  229.                                     pixman_image_t *    src_image,
  230.                                     pixman_image_t *    mask_image,
  231.                                     pixman_image_t *    dest_image,
  232.                                     int32_t             src_x,
  233.                                     int32_t             src_y,
  234.                                     int32_t             mask_x,
  235.                                     int32_t             mask_y,
  236.                                     int32_t             dest_x,
  237.                                     int32_t             dest_y,
  238.                                     int32_t             width,
  239.                                     int32_t             height)
  240. {
  241.     region->extents.x1 = dest_x;
  242.     region->extents.x2 = dest_x + width;
  243.     region->extents.y1 = dest_y;
  244.     region->extents.y2 = dest_y + height;
  245.  
  246.     region->extents.x1 = MAX (region->extents.x1, 0);
  247.     region->extents.y1 = MAX (region->extents.y1, 0);
  248.     region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width);
  249.     region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height);
  250.  
  251.     region->data = 0;
  252.  
  253.     /* Check for empty operation */
  254.     if (region->extents.x1 >= region->extents.x2 ||
  255.         region->extents.y1 >= region->extents.y2)
  256.     {
  257.         region->extents.x1 = 0;
  258.         region->extents.x2 = 0;
  259.         region->extents.y1 = 0;
  260.         region->extents.y2 = 0;
  261.         return FALSE;
  262.     }
  263.  
  264.     if (dest_image->common.have_clip_region)
  265.     {
  266.         if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
  267.             return FALSE;
  268.     }
  269.  
  270.     if (dest_image->common.alpha_map)
  271.     {
  272.         if (!pixman_region32_intersect_rect (region, region,
  273.                                              dest_image->common.alpha_origin_x,
  274.                                              dest_image->common.alpha_origin_y,
  275.                                              dest_image->common.alpha_map->width,
  276.                                              dest_image->common.alpha_map->height))
  277.         {
  278.             return FALSE;
  279.         }
  280.         if (!pixman_region32_not_empty (region))
  281.             return FALSE;
  282.         if (dest_image->common.alpha_map->common.have_clip_region)
  283.         {
  284.             if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region,
  285.                                      -dest_image->common.alpha_origin_x,
  286.                                      -dest_image->common.alpha_origin_y))
  287.             {
  288.                 return FALSE;
  289.             }
  290.         }
  291.     }
  292.  
  293.     /* clip against src */
  294.     if (src_image->common.have_clip_region)
  295.     {
  296.         if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
  297.             return FALSE;
  298.     }
  299.     if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
  300.     {
  301.         if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
  302.                                 dest_x - (src_x - src_image->common.alpha_origin_x),
  303.                                 dest_y - (src_y - src_image->common.alpha_origin_y)))
  304.         {
  305.             return FALSE;
  306.         }
  307.     }
  308.     /* clip against mask */
  309.     if (mask_image && mask_image->common.have_clip_region)
  310.     {
  311.         if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
  312.             return FALSE;
  313.  
  314.         if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
  315.         {
  316.             if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
  317.                                     dest_x - (mask_x - mask_image->common.alpha_origin_x),
  318.                                     dest_y - (mask_y - mask_image->common.alpha_origin_y)))
  319.             {
  320.                 return FALSE;
  321.             }
  322.         }
  323.     }
  324.  
  325.     return TRUE;
  326. }
  327.  
  328. typedef struct
  329. {
  330.     pixman_fixed_48_16_t        x1;
  331.     pixman_fixed_48_16_t        y1;
  332.     pixman_fixed_48_16_t        x2;
  333.     pixman_fixed_48_16_t        y2;
  334. } box_48_16_t;
  335.  
  336. static pixman_bool_t
  337. compute_transformed_extents (pixman_transform_t *transform,
  338.                              const pixman_box32_t *extents,
  339.                              box_48_16_t *transformed)
  340. {
  341.     pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
  342.     pixman_fixed_t x1, y1, x2, y2;
  343.     int i;
  344.  
  345.     x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
  346.     y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
  347.     x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
  348.     y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
  349.  
  350.     if (!transform)
  351.     {
  352.         transformed->x1 = x1;
  353.         transformed->y1 = y1;
  354.         transformed->x2 = x2;
  355.         transformed->y2 = y2;
  356.  
  357.         return TRUE;
  358.     }
  359.  
  360.     tx1 = ty1 = INT64_MAX;
  361.     tx2 = ty2 = INT64_MIN;
  362.  
  363.     for (i = 0; i < 4; ++i)
  364.     {
  365.         pixman_fixed_48_16_t tx, ty;
  366.         pixman_vector_t v;
  367.  
  368.         v.vector[0] = (i & 0x01)? x1 : x2;
  369.         v.vector[1] = (i & 0x02)? y1 : y2;
  370.         v.vector[2] = pixman_fixed_1;
  371.  
  372.         if (!pixman_transform_point (transform, &v))
  373.             return FALSE;
  374.  
  375.         tx = (pixman_fixed_48_16_t)v.vector[0];
  376.         ty = (pixman_fixed_48_16_t)v.vector[1];
  377.  
  378.         if (tx < tx1)
  379.             tx1 = tx;
  380.         if (ty < ty1)
  381.             ty1 = ty;
  382.         if (tx > tx2)
  383.             tx2 = tx;
  384.         if (ty > ty2)
  385.             ty2 = ty;
  386.     }
  387.  
  388.     transformed->x1 = tx1;
  389.     transformed->y1 = ty1;
  390.     transformed->x2 = tx2;
  391.     transformed->y2 = ty2;
  392.  
  393.     return TRUE;
  394. }
  395.  
  396. #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
  397. #define ABS(f)      (((f) < 0)?  (-(f)) : (f))
  398. #define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16)))
  399.  
  400. static pixman_bool_t
  401. analyze_extent (pixman_image_t       *image,
  402.                 const pixman_box32_t *extents,
  403.                 uint32_t             *flags)
  404. {
  405.     pixman_transform_t *transform;
  406.     pixman_fixed_t x_off, y_off;
  407.     pixman_fixed_t width, height;
  408.     pixman_fixed_t *params;
  409.     box_48_16_t transformed;
  410.     pixman_box32_t exp_extents;
  411.  
  412.     if (!image)
  413.         return TRUE;
  414.  
  415.     /* Some compositing functions walk one step
  416.      * outside the destination rectangle, so we
  417.      * check here that the expanded-by-one source
  418.      * extents in destination space fits in 16 bits
  419.      */
  420.     if (!IS_16BIT (extents->x1 - 1)             ||
  421.         !IS_16BIT (extents->y1 - 1)             ||
  422.         !IS_16BIT (extents->x2 + 1)             ||
  423.         !IS_16BIT (extents->y2 + 1))
  424.     {
  425.         return FALSE;
  426.     }
  427.  
  428.     transform = image->common.transform;
  429.     if (image->common.type == BITS)
  430.     {
  431.         /* During repeat mode calculations we might convert the
  432.          * width/height of an image to fixed 16.16, so we need
  433.          * them to be smaller than 16 bits.
  434.          */
  435.         if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
  436.             return FALSE;
  437.  
  438.         if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM &&
  439.             extents->x1 >= 0 &&
  440.             extents->y1 >= 0 &&
  441.             extents->x2 <= image->bits.width &&
  442.             extents->y2 <= image->bits.height)
  443.         {
  444.             *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
  445.             return TRUE;
  446.         }
  447.  
  448.         switch (image->common.filter)
  449.         {
  450.         case PIXMAN_FILTER_CONVOLUTION:
  451.             params = image->common.filter_params;
  452.             x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
  453.             y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
  454.             width = params[0];
  455.             height = params[1];
  456.             break;
  457.  
  458.         case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
  459.             params = image->common.filter_params;
  460.             x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
  461.             y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
  462.             width = params[0];
  463.             height = params[1];
  464.             break;
  465.            
  466.         case PIXMAN_FILTER_GOOD:
  467.         case PIXMAN_FILTER_BEST:
  468.         case PIXMAN_FILTER_BILINEAR:
  469.             x_off = - pixman_fixed_1 / 2;
  470.             y_off = - pixman_fixed_1 / 2;
  471.             width = pixman_fixed_1;
  472.             height = pixman_fixed_1;
  473.             break;
  474.  
  475.         case PIXMAN_FILTER_FAST:
  476.         case PIXMAN_FILTER_NEAREST:
  477.             x_off = - pixman_fixed_e;
  478.             y_off = - pixman_fixed_e;
  479.             width = 0;
  480.             height = 0;
  481.             break;
  482.  
  483.         default:
  484.             return FALSE;
  485.         }
  486.     }
  487.     else
  488.     {
  489.         x_off = 0;
  490.         y_off = 0;
  491.         width = 0;
  492.         height = 0;
  493.     }
  494.  
  495.     if (!compute_transformed_extents (transform, extents, &transformed))
  496.         return FALSE;
  497.  
  498.     /* Expand the source area by a tiny bit so account of different rounding that
  499.      * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
  500.      * 0.5 so this won't cause the area computed to be overly pessimistic.
  501.      */
  502.     transformed.x1 -= 8 * pixman_fixed_e;
  503.     transformed.y1 -= 8 * pixman_fixed_e;
  504.     transformed.x2 += 8 * pixman_fixed_e;
  505.     transformed.y2 += 8 * pixman_fixed_e;
  506.  
  507.     if (image->common.type == BITS)
  508.     {
  509.         if (pixman_fixed_to_int (transformed.x1) >= 0                   &&
  510.             pixman_fixed_to_int (transformed.y1) >= 0                   &&
  511.             pixman_fixed_to_int (transformed.x2) < image->bits.width    &&
  512.             pixman_fixed_to_int (transformed.y2) < image->bits.height)
  513.         {
  514.             *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
  515.         }
  516.  
  517.         if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0                &&
  518.             pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0                &&
  519.             pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width &&
  520.             pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height)
  521.         {
  522.             *flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR;
  523.         }
  524.     }
  525.  
  526.     /* Check we don't overflow when the destination extents are expanded by one.
  527.      * This ensures that compositing functions can simply walk the source space
  528.      * using 16.16 variables without worrying about overflow.
  529.      */
  530.     exp_extents = *extents;
  531.     exp_extents.x1 -= 1;
  532.     exp_extents.y1 -= 1;
  533.     exp_extents.x2 += 1;
  534.     exp_extents.y2 += 1;
  535.  
  536.     if (!compute_transformed_extents (transform, &exp_extents, &transformed))
  537.         return FALSE;
  538.    
  539.     if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e) ||
  540.         !IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e) ||
  541.         !IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width) ||
  542.         !IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height))
  543.     {
  544.         return FALSE;
  545.     }
  546.  
  547.     return TRUE;
  548. }
  549.  
  550. /*
  551.  * Work around GCC bug causing crashes in Mozilla with SSE2
  552.  *
  553.  * When using -msse, gcc generates movdqa instructions assuming that
  554.  * the stack is 16 byte aligned. Unfortunately some applications, such
  555.  * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
  556.  * causes the movdqa instructions to fail.
  557.  *
  558.  * The __force_align_arg_pointer__ makes gcc generate a prologue that
  559.  * realigns the stack pointer to 16 bytes.
  560.  *
  561.  * On x86-64 this is not necessary because the standard ABI already
  562.  * calls for a 16 byte aligned stack.
  563.  *
  564.  * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
  565.  */
  566. #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
  567. __attribute__((__force_align_arg_pointer__))
  568. #endif
  569. PIXMAN_EXPORT void
  570. pixman_image_composite32 (pixman_op_t      op,
  571.                           pixman_image_t * src,
  572.                           pixman_image_t * mask,
  573.                           pixman_image_t * dest,
  574.                           int32_t          src_x,
  575.                           int32_t          src_y,
  576.                           int32_t          mask_x,
  577.                           int32_t          mask_y,
  578.                           int32_t          dest_x,
  579.                           int32_t          dest_y,
  580.                           int32_t          width,
  581.                           int32_t          height)
  582. {
  583.     pixman_format_code_t src_format, mask_format, dest_format;
  584.     pixman_region32_t region;
  585.     pixman_box32_t extents;
  586.     pixman_implementation_t *imp;
  587.     pixman_composite_func_t func;
  588.     pixman_composite_info_t info;
  589.     const pixman_box32_t *pbox;
  590.     int n;
  591.  
  592.     _pixman_image_validate (src);
  593.     if (mask)
  594.         _pixman_image_validate (mask);
  595.     _pixman_image_validate (dest);
  596.  
  597.     src_format = src->common.extended_format_code;
  598.     info.src_flags = src->common.flags;
  599.  
  600.     if (mask && !(mask->common.flags & FAST_PATH_IS_OPAQUE))
  601.     {
  602.         mask_format = mask->common.extended_format_code;
  603.         info.mask_flags = mask->common.flags;
  604.     }
  605.     else
  606.     {
  607.         mask_format = PIXMAN_null;
  608.         info.mask_flags = FAST_PATH_IS_OPAQUE;
  609.     }
  610.  
  611.     dest_format = dest->common.extended_format_code;
  612.     info.dest_flags = dest->common.flags;
  613.  
  614.     /* Check for pixbufs */
  615.     if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
  616.         (src->type == BITS && src->bits.bits == mask->bits.bits)           &&
  617.         (src->common.repeat == mask->common.repeat)                        &&
  618.         (info.src_flags & info.mask_flags & FAST_PATH_ID_TRANSFORM)        &&
  619.         (src_x == mask_x && src_y == mask_y))
  620.     {
  621.         if (src_format == PIXMAN_x8b8g8r8)
  622.             src_format = mask_format = PIXMAN_pixbuf;
  623.         else if (src_format == PIXMAN_x8r8g8b8)
  624.             src_format = mask_format = PIXMAN_rpixbuf;
  625.     }
  626.  
  627.     pixman_region32_init (&region);
  628.  
  629.     if (!_pixman_compute_composite_region32 (
  630.             &region, src, mask, dest,
  631.             src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
  632.     {
  633.         goto out;
  634.     }
  635.  
  636.     extents = *pixman_region32_extents (&region);
  637.  
  638.     extents.x1 -= dest_x - src_x;
  639.     extents.y1 -= dest_y - src_y;
  640.     extents.x2 -= dest_x - src_x;
  641.     extents.y2 -= dest_y - src_y;
  642.  
  643.     if (!analyze_extent (src, &extents, &info.src_flags))
  644.         goto out;
  645.  
  646.     extents.x1 -= src_x - mask_x;
  647.     extents.y1 -= src_y - mask_y;
  648.     extents.x2 -= src_x - mask_x;
  649.     extents.y2 -= src_y - mask_y;
  650.  
  651.     if (!analyze_extent (mask, &extents, &info.mask_flags))
  652.         goto out;
  653.  
  654.     /* If the clip is within the source samples, and the samples are
  655.      * opaque, then the source is effectively opaque.
  656.      */
  657. #define NEAREST_OPAQUE  (FAST_PATH_SAMPLES_OPAQUE |                     \
  658.                          FAST_PATH_NEAREST_FILTER |                     \
  659.                          FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
  660. #define BILINEAR_OPAQUE (FAST_PATH_SAMPLES_OPAQUE |                     \
  661.                          FAST_PATH_BILINEAR_FILTER |                    \
  662.                          FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR)
  663.  
  664.     if ((info.src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
  665.         (info.src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
  666.     {
  667.         info.src_flags |= FAST_PATH_IS_OPAQUE;
  668.     }
  669.  
  670.     if ((info.mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
  671.         (info.mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
  672.     {
  673.         info.mask_flags |= FAST_PATH_IS_OPAQUE;
  674.     }
  675.  
  676.     /*
  677.      * Check if we can replace our operator by a simpler one
  678.      * if the src or dest are opaque. The output operator should be
  679.      * mathematically equivalent to the source.
  680.      */
  681.     info.op = optimize_operator (op, info.src_flags, info.mask_flags, info.dest_flags);
  682.  
  683.     _pixman_implementation_lookup_composite (
  684.         get_implementation (), info.op,
  685.         src_format, info.src_flags,
  686.         mask_format, info.mask_flags,
  687.         dest_format, info.dest_flags,
  688.         &imp, &func);
  689.  
  690.     info.src_image = src;
  691.     info.mask_image = mask;
  692.     info.dest_image = dest;
  693.  
  694.     pbox = pixman_region32_rectangles (&region, &n);
  695.  
  696.     while (n--)
  697.     {
  698.         info.src_x = pbox->x1 + src_x - dest_x;
  699.         info.src_y = pbox->y1 + src_y - dest_y;
  700.         info.mask_x = pbox->x1 + mask_x - dest_x;
  701.         info.mask_y = pbox->y1 + mask_y - dest_y;
  702.         info.dest_x = pbox->x1;
  703.         info.dest_y = pbox->y1;
  704.         info.width = pbox->x2 - pbox->x1;
  705.         info.height = pbox->y2 - pbox->y1;
  706.  
  707.         func (imp, &info);
  708.  
  709.         pbox++;
  710.     }
  711.  
  712. out:
  713.     pixman_region32_fini (&region);
  714. }
  715.  
  716. PIXMAN_EXPORT void
  717. pixman_image_composite (pixman_op_t      op,
  718.                         pixman_image_t * src,
  719.                         pixman_image_t * mask,
  720.                         pixman_image_t * dest,
  721.                         int16_t          src_x,
  722.                         int16_t          src_y,
  723.                         int16_t          mask_x,
  724.                         int16_t          mask_y,
  725.                         int16_t          dest_x,
  726.                         int16_t          dest_y,
  727.                         uint16_t         width,
  728.                         uint16_t         height)
  729. {
  730.     pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
  731.                               mask_x, mask_y, dest_x, dest_y, width, height);
  732. }
  733.  
  734. PIXMAN_EXPORT pixman_bool_t
  735. pixman_blt (uint32_t *src_bits,
  736.             uint32_t *dst_bits,
  737.             int       src_stride,
  738.             int       dst_stride,
  739.             int       src_bpp,
  740.             int       dst_bpp,
  741.             int       src_x,
  742.             int       src_y,
  743.             int       dest_x,
  744.             int       dest_y,
  745.             int       width,
  746.             int       height)
  747. {
  748.     return _pixman_implementation_blt (get_implementation(),
  749.                                        src_bits, dst_bits, src_stride, dst_stride,
  750.                                        src_bpp, dst_bpp,
  751.                                        src_x, src_y,
  752.                                        dest_x, dest_y,
  753.                                        width, height);
  754. }
  755.  
  756. PIXMAN_EXPORT pixman_bool_t
  757. pixman_fill (uint32_t *bits,
  758.              int       stride,
  759.              int       bpp,
  760.              int       x,
  761.              int       y,
  762.              int       width,
  763.              int       height,
  764.              uint32_t  filler)
  765. {
  766.     return _pixman_implementation_fill (
  767.         get_implementation(), bits, stride, bpp, x, y, width, height, filler);
  768. }
  769.  
  770. static uint32_t
  771. color_to_uint32 (const pixman_color_t *color)
  772. {
  773.     return
  774.         (color->alpha >> 8 << 24) |
  775.         (color->red >> 8 << 16) |
  776.         (color->green & 0xff00) |
  777.         (color->blue >> 8);
  778. }
  779.  
  780. static pixman_bool_t
  781. color_to_pixel (const pixman_color_t *color,
  782.                 uint32_t *            pixel,
  783.                 pixman_format_code_t  format)
  784. {
  785.     uint32_t c = color_to_uint32 (color);
  786.  
  787.     if (!(format == PIXMAN_a8r8g8b8     ||
  788.           format == PIXMAN_x8r8g8b8     ||
  789.           format == PIXMAN_a8b8g8r8     ||
  790.           format == PIXMAN_x8b8g8r8     ||
  791.           format == PIXMAN_b8g8r8a8     ||
  792.           format == PIXMAN_b8g8r8x8     ||
  793.           format == PIXMAN_r8g8b8a8     ||
  794.           format == PIXMAN_r8g8b8x8     ||
  795.           format == PIXMAN_r5g6b5       ||
  796.           format == PIXMAN_b5g6r5       ||
  797.           format == PIXMAN_a8           ||
  798.           format == PIXMAN_a1))
  799.     {
  800.         return FALSE;
  801.     }
  802.  
  803.     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
  804.     {
  805.         c = ((c & 0xff000000) >>  0) |
  806.             ((c & 0x00ff0000) >> 16) |
  807.             ((c & 0x0000ff00) >>  0) |
  808.             ((c & 0x000000ff) << 16);
  809.     }
  810.     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
  811.     {
  812.         c = ((c & 0xff000000) >> 24) |
  813.             ((c & 0x00ff0000) >>  8) |
  814.             ((c & 0x0000ff00) <<  8) |
  815.             ((c & 0x000000ff) << 24);
  816.     }
  817.     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA)
  818.         c = ((c & 0xff000000) >> 24) | (c << 8);
  819.  
  820.     if (format == PIXMAN_a1)
  821.         c = c >> 31;
  822.     else if (format == PIXMAN_a8)
  823.         c = c >> 24;
  824.     else if (format == PIXMAN_r5g6b5 ||
  825.              format == PIXMAN_b5g6r5)
  826.         c = convert_8888_to_0565 (c);
  827.  
  828. #if 0
  829.     printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
  830.     printf ("pixel: %x\n", c);
  831. #endif
  832.  
  833.     *pixel = c;
  834.     return TRUE;
  835. }
  836.  
  837. PIXMAN_EXPORT pixman_bool_t
  838. pixman_image_fill_rectangles (pixman_op_t                 op,
  839.                               pixman_image_t *            dest,
  840.                               const pixman_color_t *      color,
  841.                               int                         n_rects,
  842.                               const pixman_rectangle16_t *rects)
  843. {
  844.     pixman_box32_t stack_boxes[6];
  845.     pixman_box32_t *boxes;
  846.     pixman_bool_t result;
  847.     int i;
  848.  
  849.     if (n_rects > 6)
  850.     {
  851.         boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
  852.         if (boxes == NULL)
  853.             return FALSE;
  854.     }
  855.     else
  856.     {
  857.         boxes = stack_boxes;
  858.     }
  859.  
  860.     for (i = 0; i < n_rects; ++i)
  861.     {
  862.         boxes[i].x1 = rects[i].x;
  863.         boxes[i].y1 = rects[i].y;
  864.         boxes[i].x2 = boxes[i].x1 + rects[i].width;
  865.         boxes[i].y2 = boxes[i].y1 + rects[i].height;
  866.     }
  867.  
  868.     result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
  869.  
  870.     if (boxes != stack_boxes)
  871.         free (boxes);
  872.    
  873.     return result;
  874. }
  875.  
  876. PIXMAN_EXPORT pixman_bool_t
  877. pixman_image_fill_boxes (pixman_op_t           op,
  878.                          pixman_image_t *      dest,
  879.                          const pixman_color_t *color,
  880.                          int                   n_boxes,
  881.                          const pixman_box32_t *boxes)
  882. {
  883.     pixman_image_t *solid;
  884.     pixman_color_t c;
  885.     int i;
  886.  
  887.     _pixman_image_validate (dest);
  888.    
  889.     if (color->alpha == 0xffff)
  890.     {
  891.         if (op == PIXMAN_OP_OVER)
  892.             op = PIXMAN_OP_SRC;
  893.     }
  894.  
  895.     if (op == PIXMAN_OP_CLEAR)
  896.     {
  897.         c.red = 0;
  898.         c.green = 0;
  899.         c.blue = 0;
  900.         c.alpha = 0;
  901.  
  902.         color = &c;
  903.  
  904.         op = PIXMAN_OP_SRC;
  905.     }
  906.  
  907.     if (op == PIXMAN_OP_SRC)
  908.     {
  909.         uint32_t pixel;
  910.  
  911.         if (color_to_pixel (color, &pixel, dest->bits.format))
  912.         {
  913.             pixman_region32_t fill_region;
  914.             int n_rects, j;
  915.             pixman_box32_t *rects;
  916.  
  917.             if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
  918.                 return FALSE;
  919.  
  920.             if (dest->common.have_clip_region)
  921.             {
  922.                 if (!pixman_region32_intersect (&fill_region,
  923.                                                 &fill_region,
  924.                                                 &dest->common.clip_region))
  925.                     return FALSE;
  926.             }
  927.  
  928.             rects = pixman_region32_rectangles (&fill_region, &n_rects);
  929.             for (j = 0; j < n_rects; ++j)
  930.             {
  931.                 const pixman_box32_t *rect = &(rects[j]);
  932.                 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
  933.                              rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
  934.                              pixel);
  935.             }
  936.  
  937.             pixman_region32_fini (&fill_region);
  938.             return TRUE;
  939.         }
  940.     }
  941.  
  942.     solid = pixman_image_create_solid_fill (color);
  943.     if (!solid)
  944.         return FALSE;
  945.  
  946.     for (i = 0; i < n_boxes; ++i)
  947.     {
  948.         const pixman_box32_t *box = &(boxes[i]);
  949.  
  950.         pixman_image_composite32 (op, solid, NULL, dest,
  951.                                   0, 0, 0, 0,
  952.                                   box->x1, box->y1,
  953.                                   box->x2 - box->x1, box->y2 - box->y1);
  954.     }
  955.  
  956.     pixman_image_unref (solid);
  957.  
  958.     return TRUE;
  959. }
  960.  
  961. /**
  962.  * pixman_version:
  963.  *
  964.  * Returns the version of the pixman library encoded in a single
  965.  * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
  966.  * later versions compare greater than earlier versions.
  967.  *
  968.  * A run-time comparison to check that pixman's version is greater than
  969.  * or equal to version X.Y.Z could be performed as follows:
  970.  *
  971.  * <informalexample><programlisting>
  972.  * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
  973.  * </programlisting></informalexample>
  974.  *
  975.  * See also pixman_version_string() as well as the compile-time
  976.  * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
  977.  *
  978.  * Return value: the encoded version.
  979.  **/
  980. PIXMAN_EXPORT int
  981. pixman_version (void)
  982. {
  983.     return PIXMAN_VERSION;
  984. }
  985.  
  986. /**
  987.  * pixman_version_string:
  988.  *
  989.  * Returns the version of the pixman library as a human-readable string
  990.  * of the form "X.Y.Z".
  991.  *
  992.  * See also pixman_version() as well as the compile-time equivalents
  993.  * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
  994.  *
  995.  * Return value: a string containing the version.
  996.  **/
  997. PIXMAN_EXPORT const char*
  998. pixman_version_string (void)
  999. {
  1000.     return PIXMAN_VERSION_STRING;
  1001. }
  1002.  
  1003. /**
  1004.  * pixman_format_supported_source:
  1005.  * @format: A pixman_format_code_t format
  1006.  *
  1007.  * Return value: whether the provided format code is a supported
  1008.  * format for a pixman surface used as a source in
  1009.  * rendering.
  1010.  *
  1011.  * Currently, all pixman_format_code_t values are supported.
  1012.  **/
  1013. PIXMAN_EXPORT pixman_bool_t
  1014. pixman_format_supported_source (pixman_format_code_t format)
  1015. {
  1016.     switch (format)
  1017.     {
  1018.     /* 32 bpp formats */
  1019.     case PIXMAN_a2b10g10r10:
  1020.     case PIXMAN_x2b10g10r10:
  1021.     case PIXMAN_a2r10g10b10:
  1022.     case PIXMAN_x2r10g10b10:
  1023.     case PIXMAN_a8r8g8b8:
  1024.     case PIXMAN_a8r8g8b8_sRGB:
  1025.     case PIXMAN_x8r8g8b8:
  1026.     case PIXMAN_a8b8g8r8:
  1027.     case PIXMAN_x8b8g8r8:
  1028.     case PIXMAN_b8g8r8a8:
  1029.     case PIXMAN_b8g8r8x8:
  1030.     case PIXMAN_r8g8b8a8:
  1031.     case PIXMAN_r8g8b8x8:
  1032.     case PIXMAN_r8g8b8:
  1033.     case PIXMAN_b8g8r8:
  1034.     case PIXMAN_r5g6b5:
  1035.     case PIXMAN_b5g6r5:
  1036.     case PIXMAN_x14r6g6b6:
  1037.     /* 16 bpp formats */
  1038.     case PIXMAN_a1r5g5b5:
  1039.     case PIXMAN_x1r5g5b5:
  1040.     case PIXMAN_a1b5g5r5:
  1041.     case PIXMAN_x1b5g5r5:
  1042.     case PIXMAN_a4r4g4b4:
  1043.     case PIXMAN_x4r4g4b4:
  1044.     case PIXMAN_a4b4g4r4:
  1045.     case PIXMAN_x4b4g4r4:
  1046.     /* 8bpp formats */
  1047.     case PIXMAN_a8:
  1048.     case PIXMAN_r3g3b2:
  1049.     case PIXMAN_b2g3r3:
  1050.     case PIXMAN_a2r2g2b2:
  1051.     case PIXMAN_a2b2g2r2:
  1052.     case PIXMAN_c8:
  1053.     case PIXMAN_g8:
  1054.     case PIXMAN_x4a4:
  1055.     /* Collides with PIXMAN_c8
  1056.        case PIXMAN_x4c4:
  1057.      */
  1058.     /* Collides with PIXMAN_g8
  1059.        case PIXMAN_x4g4:
  1060.      */
  1061.     /* 4bpp formats */
  1062.     case PIXMAN_a4:
  1063.     case PIXMAN_r1g2b1:
  1064.     case PIXMAN_b1g2r1:
  1065.     case PIXMAN_a1r1g1b1:
  1066.     case PIXMAN_a1b1g1r1:
  1067.     case PIXMAN_c4:
  1068.     case PIXMAN_g4:
  1069.     /* 1bpp formats */
  1070.     case PIXMAN_a1:
  1071.     case PIXMAN_g1:
  1072.     /* YUV formats */
  1073.     case PIXMAN_yuy2:
  1074.     case PIXMAN_yv12:
  1075.         return TRUE;
  1076.  
  1077.     default:
  1078.         return FALSE;
  1079.     }
  1080. }
  1081.  
  1082. /**
  1083.  * pixman_format_supported_destination:
  1084.  * @format: A pixman_format_code_t format
  1085.  *
  1086.  * Return value: whether the provided format code is a supported
  1087.  * format for a pixman surface used as a destination in
  1088.  * rendering.
  1089.  *
  1090.  * Currently, all pixman_format_code_t values are supported
  1091.  * except for the YUV formats.
  1092.  **/
  1093. PIXMAN_EXPORT pixman_bool_t
  1094. pixman_format_supported_destination (pixman_format_code_t format)
  1095. {
  1096.     /* YUV formats cannot be written to at the moment */
  1097.     if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
  1098.         return FALSE;
  1099.  
  1100.     return pixman_format_supported_source (format);
  1101. }
  1102.  
  1103. PIXMAN_EXPORT pixman_bool_t
  1104. pixman_compute_composite_region (pixman_region16_t * region,
  1105.                                  pixman_image_t *    src_image,
  1106.                                  pixman_image_t *    mask_image,
  1107.                                  pixman_image_t *    dest_image,
  1108.                                  int16_t             src_x,
  1109.                                  int16_t             src_y,
  1110.                                  int16_t             mask_x,
  1111.                                  int16_t             mask_y,
  1112.                                  int16_t             dest_x,
  1113.                                  int16_t             dest_y,
  1114.                                  uint16_t            width,
  1115.                                  uint16_t            height)
  1116. {
  1117.     pixman_region32_t r32;
  1118.     pixman_bool_t retval;
  1119.  
  1120.     pixman_region32_init (&r32);
  1121.  
  1122.     retval = _pixman_compute_composite_region32 (
  1123.         &r32, src_image, mask_image, dest_image,
  1124.         src_x, src_y, mask_x, mask_y, dest_x, dest_y,
  1125.         width, height);
  1126.  
  1127.     if (retval)
  1128.     {
  1129.         if (!pixman_region16_copy_from_region32 (region, &r32))
  1130.             retval = FALSE;
  1131.     }
  1132.  
  1133.     pixman_region32_fini (&r32);
  1134.     return retval;
  1135. }
  1136.