LCOV - code coverage report
Current view: top level - gfx/cairo/libpixman/src - pixman.c (source / functions) Hit Total Coverage
Test: output.info Lines: 89 375 23.7 %
Date: 2017-07-14 16:53:18 Functions: 4 19 21.1 %
Legend: Lines: hit not hit

          Line data    Source code
       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          22 : 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          22 :     is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
     147          22 :     is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
     148             : 
     149          22 :     is_dest_opaque >>= OPAQUE_SHIFT - 1;
     150          22 :     is_source_opaque >>= OPAQUE_SHIFT;
     151             : 
     152          22 :     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           0 : clip_general_image (pixman_region32_t * region,
     160             :                     pixman_region32_t * clip,
     161             :                     int                 dx,
     162             :                     int                 dy)
     163             : {
     164           0 :     if (pixman_region32_n_rects (region) == 1 &&
     165           0 :         pixman_region32_n_rects (clip) == 1)
     166           0 :     {
     167           0 :         pixman_box32_t *  rbox = pixman_region32_rectangles (region, NULL);
     168           0 :         pixman_box32_t *  cbox = pixman_region32_rectangles (clip, NULL);
     169             :         int v;
     170             : 
     171           0 :         if (rbox->x1 < (v = cbox->x1 + dx))
     172           0 :             rbox->x1 = v;
     173           0 :         if (rbox->x2 > (v = cbox->x2 + dx))
     174           0 :             rbox->x2 = v;
     175           0 :         if (rbox->y1 < (v = cbox->y1 + dy))
     176           0 :             rbox->y1 = v;
     177           0 :         if (rbox->y2 > (v = cbox->y2 + dy))
     178           0 :             rbox->y2 = v;
     179           0 :         if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
     180             :         {
     181           0 :             pixman_region32_init (region);
     182           0 :             return FALSE;
     183             :         }
     184             :     }
     185           0 :     else if (!pixman_region32_not_empty (clip))
     186             :     {
     187           0 :         return FALSE;
     188             :     }
     189             :     else
     190             :     {
     191           0 :         if (dx || dy)
     192           0 :             pixman_region32_translate (region, -dx, -dy);
     193             : 
     194           0 :         if (!pixman_region32_intersect (region, region, clip))
     195           0 :             return FALSE;
     196             : 
     197           0 :         if (dx || dy)
     198           0 :             pixman_region32_translate (region, dx, dy);
     199             :     }
     200             : 
     201           0 :     return pixman_region32_not_empty (region);
     202             : }
     203             : 
     204             : static inline pixman_bool_t
     205           0 : 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           0 :     if (!image->common.clip_sources || !image->common.client_clip)
     216           0 :         return TRUE;
     217             : 
     218           0 :     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          22 : _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          22 :     region->extents.x1 = dest_x;
     242          22 :     region->extents.x2 = dest_x + width;
     243          22 :     region->extents.y1 = dest_y;
     244          22 :     region->extents.y2 = dest_y + height;
     245             : 
     246          22 :     region->extents.x1 = MAX (region->extents.x1, 0);
     247          22 :     region->extents.y1 = MAX (region->extents.y1, 0);
     248          22 :     region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width);
     249          22 :     region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height);
     250             : 
     251          22 :     region->data = 0;
     252             : 
     253             :     /* Check for empty operation */
     254          44 :     if (region->extents.x1 >= region->extents.x2 ||
     255          22 :         region->extents.y1 >= region->extents.y2)
     256             :     {
     257           0 :         region->extents.x1 = 0;
     258           0 :         region->extents.x2 = 0;
     259           0 :         region->extents.y1 = 0;
     260           0 :         region->extents.y2 = 0;
     261           0 :         return FALSE;
     262             :     }
     263             : 
     264          22 :     if (dest_image->common.have_clip_region)
     265             :     {
     266           0 :         if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
     267           0 :             return FALSE;
     268             :     }
     269             : 
     270          22 :     if (dest_image->common.alpha_map)
     271             :     {
     272           0 :         if (!pixman_region32_intersect_rect (region, region,
     273             :                                              dest_image->common.alpha_origin_x,
     274             :                                              dest_image->common.alpha_origin_y,
     275           0 :                                              dest_image->common.alpha_map->width,
     276           0 :                                              dest_image->common.alpha_map->height))
     277             :         {
     278           0 :             return FALSE;
     279             :         }
     280           0 :         if (!pixman_region32_not_empty (region))
     281           0 :             return FALSE;
     282           0 :         if (dest_image->common.alpha_map->common.have_clip_region)
     283             :         {
     284           0 :             if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region,
     285           0 :                                      -dest_image->common.alpha_origin_x,
     286           0 :                                      -dest_image->common.alpha_origin_y))
     287             :             {
     288           0 :                 return FALSE;
     289             :             }
     290             :         }
     291             :     }
     292             : 
     293             :     /* clip against src */
     294          22 :     if (src_image->common.have_clip_region)
     295             :     {
     296           0 :         if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
     297           0 :             return FALSE;
     298             :     }
     299          22 :     if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
     300             :     {
     301           0 :         if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
     302           0 :                                 dest_x - (src_x - src_image->common.alpha_origin_x),
     303           0 :                                 dest_y - (src_y - src_image->common.alpha_origin_y)))
     304             :         {
     305           0 :             return FALSE;
     306             :         }
     307             :     }
     308             :     /* clip against mask */
     309          22 :     if (mask_image && mask_image->common.have_clip_region)
     310             :     {
     311           0 :         if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
     312           0 :             return FALSE;
     313             : 
     314           0 :         if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
     315             :         {
     316           0 :             if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
     317           0 :                                     dest_x - (mask_x - mask_image->common.alpha_origin_x),
     318           0 :                                     dest_y - (mask_y - mask_image->common.alpha_origin_y)))
     319             :             {
     320           0 :                 return FALSE;
     321             :             }
     322             :         }
     323             :     }
     324             : 
     325          22 :     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           0 : 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           0 :     x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
     346           0 :     y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
     347           0 :     x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
     348           0 :     y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
     349             : 
     350           0 :     if (!transform)
     351             :     {
     352           0 :         transformed->x1 = x1;
     353           0 :         transformed->y1 = y1;
     354           0 :         transformed->x2 = x2;
     355           0 :         transformed->y2 = y2;
     356             : 
     357           0 :         return TRUE;
     358             :     }
     359             : 
     360           0 :     tx1 = ty1 = INT64_MAX;
     361           0 :     tx2 = ty2 = INT64_MIN;
     362             : 
     363           0 :     for (i = 0; i < 4; ++i)
     364             :     {
     365             :         pixman_fixed_48_16_t tx, ty;
     366             :         pixman_vector_t v;
     367             : 
     368           0 :         v.vector[0] = (i & 0x01)? x1 : x2;
     369           0 :         v.vector[1] = (i & 0x02)? y1 : y2;
     370           0 :         v.vector[2] = pixman_fixed_1;
     371             : 
     372           0 :         if (!pixman_transform_point (transform, &v))
     373           0 :             return FALSE;
     374             : 
     375           0 :         tx = (pixman_fixed_48_16_t)v.vector[0];
     376           0 :         ty = (pixman_fixed_48_16_t)v.vector[1];
     377             : 
     378           0 :         if (tx < tx1)
     379           0 :             tx1 = tx;
     380           0 :         if (ty < ty1)
     381           0 :             ty1 = ty;
     382           0 :         if (tx > tx2)
     383           0 :             tx2 = tx;
     384           0 :         if (ty > ty2)
     385           0 :             ty2 = ty;
     386             :     }
     387             : 
     388           0 :     transformed->x1 = tx1;
     389           0 :     transformed->y1 = ty1;
     390           0 :     transformed->x2 = tx2;
     391           0 :     transformed->y2 = ty2;
     392             : 
     393           0 :     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          44 : 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          44 :     if (!image)
     413          22 :         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          44 :     if (!IS_16BIT (extents->x1 - 1)          ||
     421          66 :         !IS_16BIT (extents->y1 - 1)          ||
     422          66 :         !IS_16BIT (extents->x2 + 1)          ||
     423          44 :         !IS_16BIT (extents->y2 + 1))
     424             :     {
     425           0 :         return FALSE;
     426             :     }
     427             : 
     428          22 :     transform = image->common.transform;
     429          22 :     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          22 :         if (image->bits.width >= 0x7fff   || image->bits.height >= 0x7fff)
     436           0 :             return FALSE;
     437             : 
     438          44 :         if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM &&
     439          44 :             extents->x1 >= 0 &&
     440          44 :             extents->y1 >= 0 &&
     441          44 :             extents->x2 <= image->bits.width &&
     442          22 :             extents->y2 <= image->bits.height)
     443             :         {
     444          22 :             *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
     445          22 :             return TRUE;
     446             :         }
     447             : 
     448           0 :         switch (image->common.filter)
     449             :         {
     450             :         case PIXMAN_FILTER_CONVOLUTION:
     451           0 :             params = image->common.filter_params;
     452           0 :             x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
     453           0 :             y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
     454           0 :             width = params[0];
     455           0 :             height = params[1];
     456           0 :             break;
     457             : 
     458             :         case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
     459           0 :             params = image->common.filter_params;
     460           0 :             x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
     461           0 :             y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
     462           0 :             width = params[0];
     463           0 :             height = params[1];
     464           0 :             break;
     465             :             
     466             :         case PIXMAN_FILTER_GOOD:
     467             :         case PIXMAN_FILTER_BEST:
     468             :         case PIXMAN_FILTER_BILINEAR:
     469           0 :             x_off = - pixman_fixed_1 / 2;
     470           0 :             y_off = - pixman_fixed_1 / 2;
     471           0 :             width = pixman_fixed_1;
     472           0 :             height = pixman_fixed_1;
     473           0 :             break;
     474             : 
     475             :         case PIXMAN_FILTER_FAST:
     476             :         case PIXMAN_FILTER_NEAREST:
     477           0 :             x_off = - pixman_fixed_e;
     478           0 :             y_off = - pixman_fixed_e;
     479           0 :             width = 0;
     480           0 :             height = 0;
     481           0 :             break;
     482             : 
     483             :         default:
     484           0 :             return FALSE;
     485             :         }
     486             :     }
     487             :     else
     488             :     {
     489           0 :         x_off = 0;
     490           0 :         y_off = 0;
     491           0 :         width = 0;
     492           0 :         height = 0;
     493             :     }
     494             : 
     495           0 :     if (!compute_transformed_extents (transform, extents, &transformed))
     496           0 :         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           0 :     transformed.x1 -= 8 * pixman_fixed_e;
     503           0 :     transformed.y1 -= 8 * pixman_fixed_e;
     504           0 :     transformed.x2 += 8 * pixman_fixed_e;
     505           0 :     transformed.y2 += 8 * pixman_fixed_e;
     506             : 
     507           0 :     if (image->common.type == BITS)
     508             :     {
     509           0 :         if (pixman_fixed_to_int (transformed.x1) >= 0                        &&
     510           0 :             pixman_fixed_to_int (transformed.y1) >= 0                        &&
     511           0 :             pixman_fixed_to_int (transformed.x2) < image->bits.width      &&
     512           0 :             pixman_fixed_to_int (transformed.y2) < image->bits.height)
     513             :         {
     514           0 :             *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
     515             :         }
     516             : 
     517           0 :         if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0             &&
     518           0 :             pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0             &&
     519           0 :             pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width &&
     520           0 :             pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height)
     521             :         {
     522           0 :             *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           0 :     exp_extents = *extents;
     531           0 :     exp_extents.x1 -= 1;
     532           0 :     exp_extents.y1 -= 1;
     533           0 :     exp_extents.x2 += 1;
     534           0 :     exp_extents.y2 += 1;
     535             : 
     536           0 :     if (!compute_transformed_extents (transform, &exp_extents, &transformed))
     537           0 :         return FALSE;
     538             :     
     539           0 :     if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e) ||
     540           0 :         !IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e) ||
     541           0 :         !IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width) ||
     542           0 :         !IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height))
     543             :     {
     544           0 :         return FALSE;
     545             :     }
     546             : 
     547           0 :     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          22 : 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          22 :     _pixman_image_validate (src);
     593          22 :     if (mask)
     594           0 :         _pixman_image_validate (mask);
     595          22 :     _pixman_image_validate (dest);
     596             : 
     597          22 :     src_format = src->common.extended_format_code;
     598          22 :     info.src_flags = src->common.flags;
     599             : 
     600          22 :     if (mask && !(mask->common.flags & FAST_PATH_IS_OPAQUE))
     601             :     {
     602           0 :         mask_format = mask->common.extended_format_code;
     603           0 :         info.mask_flags = mask->common.flags;
     604             :     }
     605             :     else
     606             :     {
     607          22 :         mask_format = PIXMAN_null;
     608          22 :         info.mask_flags = FAST_PATH_IS_OPAQUE;
     609             :     }
     610             : 
     611          22 :     dest_format = dest->common.extended_format_code;
     612          22 :     info.dest_flags = dest->common.flags;
     613             : 
     614             :     /* Check for pixbufs */
     615          22 :     if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
     616           0 :         (src->type == BITS && src->bits.bits == mask->bits.bits)          &&
     617           0 :         (src->common.repeat == mask->common.repeat)                          &&
     618           0 :         (info.src_flags & info.mask_flags & FAST_PATH_ID_TRANSFORM)        &&
     619           0 :         (src_x == mask_x && src_y == mask_y))
     620             :     {
     621           0 :         if (src_format == PIXMAN_x8b8g8r8)
     622           0 :             src_format = mask_format = PIXMAN_pixbuf;
     623           0 :         else if (src_format == PIXMAN_x8r8g8b8)
     624           0 :             src_format = mask_format = PIXMAN_rpixbuf;
     625             :     }
     626             : 
     627          22 :     pixman_region32_init (&region);
     628             : 
     629          22 :     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           0 :         goto out;
     634             :     }
     635             : 
     636          22 :     extents = *pixman_region32_extents (&region);
     637             : 
     638          22 :     extents.x1 -= dest_x - src_x;
     639          22 :     extents.y1 -= dest_y - src_y;
     640          22 :     extents.x2 -= dest_x - src_x;
     641          22 :     extents.y2 -= dest_y - src_y;
     642             : 
     643          22 :     if (!analyze_extent (src, &extents, &info.src_flags))
     644           0 :         goto out;
     645             : 
     646          22 :     extents.x1 -= src_x - mask_x;
     647          22 :     extents.y1 -= src_y - mask_y;
     648          22 :     extents.x2 -= src_x - mask_x;
     649          22 :     extents.y2 -= src_y - mask_y;
     650             : 
     651          22 :     if (!analyze_extent (mask, &extents, &info.mask_flags))
     652           0 :         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          44 :     if ((info.src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
     665          22 :         (info.src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
     666             :     {
     667           0 :         info.src_flags |= FAST_PATH_IS_OPAQUE;
     668             :     }
     669             : 
     670          44 :     if ((info.mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
     671          22 :         (info.mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
     672             :     {
     673           0 :         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          22 :     info.op = optimize_operator (op, info.src_flags, info.mask_flags, info.dest_flags);
     682             : 
     683          44 :     _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          22 :     info.src_image = src;
     691          22 :     info.mask_image = mask;
     692          22 :     info.dest_image = dest;
     693             : 
     694          22 :     pbox = pixman_region32_rectangles (&region, &n);
     695             : 
     696          66 :     while (n--)
     697             :     {
     698          22 :         info.src_x = pbox->x1 + src_x - dest_x;
     699          22 :         info.src_y = pbox->y1 + src_y - dest_y;
     700          22 :         info.mask_x = pbox->x1 + mask_x - dest_x;
     701          22 :         info.mask_y = pbox->y1 + mask_y - dest_y;
     702          22 :         info.dest_x = pbox->x1;
     703          22 :         info.dest_y = pbox->y1;
     704          22 :         info.width = pbox->x2 - pbox->x1;
     705          22 :         info.height = pbox->y2 - pbox->y1;
     706             : 
     707          22 :         func (imp, &info);
     708             : 
     709          22 :         pbox++;
     710             :     }
     711             : 
     712             : out:
     713          22 :     pixman_region32_fini (&region);
     714          22 : }
     715             : 
     716             : PIXMAN_EXPORT void
     717           0 : 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           0 :     pixman_image_composite32 (op, src, mask, dest, src_x, src_y, 
     731             :                               mask_x, mask_y, dest_x, dest_y, width, height);
     732           0 : }
     733             : 
     734             : PIXMAN_EXPORT pixman_bool_t
     735           0 : 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           0 :     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           0 : 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           0 :     return _pixman_implementation_fill (
     767             :         get_implementation(), bits, stride, bpp, x, y, width, height, filler);
     768             : }
     769             : 
     770             : static uint32_t
     771           0 : color_to_uint32 (const pixman_color_t *color)
     772             : {
     773             :     return
     774           0 :         (color->alpha >> 8 << 24) |
     775           0 :         (color->red >> 8 << 16) |
     776           0 :         (color->green & 0xff00) |
     777           0 :         (color->blue >> 8);
     778             : }
     779             : 
     780             : static pixman_bool_t
     781           0 : color_to_pixel (const pixman_color_t *color,
     782             :                 uint32_t *            pixel,
     783             :                 pixman_format_code_t  format)
     784             : {
     785           0 :     uint32_t c = color_to_uint32 (color);
     786             : 
     787           0 :     if (!(format == PIXMAN_a8r8g8b8     ||
     788           0 :           format == PIXMAN_x8r8g8b8     ||
     789           0 :           format == PIXMAN_a8b8g8r8     ||
     790           0 :           format == PIXMAN_x8b8g8r8     ||
     791           0 :           format == PIXMAN_b8g8r8a8     ||
     792           0 :           format == PIXMAN_b8g8r8x8     ||
     793           0 :           format == PIXMAN_r8g8b8a8     ||
     794           0 :           format == PIXMAN_r8g8b8x8     ||
     795           0 :           format == PIXMAN_r5g6b5       ||
     796           0 :           format == PIXMAN_b5g6r5       ||
     797             :           format == PIXMAN_a8           ||
     798             :           format == PIXMAN_a1))
     799             :     {
     800           0 :         return FALSE;
     801             :     }
     802             : 
     803           0 :     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
     804             :     {
     805           0 :         c = ((c & 0xff000000) >>  0) |
     806           0 :             ((c & 0x00ff0000) >> 16) |
     807           0 :             ((c & 0x0000ff00) >>  0) |
     808           0 :             ((c & 0x000000ff) << 16);
     809             :     }
     810           0 :     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
     811             :     {
     812           0 :         c = ((c & 0xff000000) >> 24) |
     813           0 :             ((c & 0x00ff0000) >>  8) |
     814           0 :             ((c & 0x0000ff00) <<  8) |
     815           0 :             ((c & 0x000000ff) << 24);
     816             :     }
     817           0 :     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA)
     818           0 :         c = ((c & 0xff000000) >> 24) | (c << 8);
     819             : 
     820           0 :     if (format == PIXMAN_a1)
     821           0 :         c = c >> 31;
     822           0 :     else if (format == PIXMAN_a8)
     823           0 :         c = c >> 24;
     824           0 :     else if (format == PIXMAN_r5g6b5 ||
     825             :              format == PIXMAN_b5g6r5)
     826           0 :         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           0 :     *pixel = c;
     834           0 :     return TRUE;
     835             : }
     836             : 
     837             : PIXMAN_EXPORT pixman_bool_t
     838           0 : 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           0 :     if (n_rects > 6)
     850             :     {
     851           0 :         boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
     852           0 :         if (boxes == NULL)
     853           0 :             return FALSE;
     854             :     }
     855             :     else
     856             :     {
     857           0 :         boxes = stack_boxes;
     858             :     }
     859             : 
     860           0 :     for (i = 0; i < n_rects; ++i)
     861             :     {
     862           0 :         boxes[i].x1 = rects[i].x;
     863           0 :         boxes[i].y1 = rects[i].y;
     864           0 :         boxes[i].x2 = boxes[i].x1 + rects[i].width;
     865           0 :         boxes[i].y2 = boxes[i].y1 + rects[i].height;
     866             :     }
     867             : 
     868           0 :     result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
     869             : 
     870           0 :     if (boxes != stack_boxes)
     871           0 :         free (boxes);
     872             :     
     873           0 :     return result;
     874             : }
     875             : 
     876             : PIXMAN_EXPORT pixman_bool_t
     877           0 : 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           0 :     _pixman_image_validate (dest);
     888             :     
     889           0 :     if (color->alpha == 0xffff)
     890             :     {
     891           0 :         if (op == PIXMAN_OP_OVER)
     892           0 :             op = PIXMAN_OP_SRC;
     893             :     }
     894             : 
     895           0 :     if (op == PIXMAN_OP_CLEAR)
     896             :     {
     897           0 :         c.red = 0;
     898           0 :         c.green = 0;
     899           0 :         c.blue = 0;
     900           0 :         c.alpha = 0;
     901             : 
     902           0 :         color = &c;
     903             : 
     904           0 :         op = PIXMAN_OP_SRC;
     905             :     }
     906             : 
     907           0 :     if (op == PIXMAN_OP_SRC)
     908             :     {
     909             :         uint32_t pixel;
     910             : 
     911           0 :         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           0 :             if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
     918           0 :                 return FALSE;
     919             : 
     920           0 :             if (dest->common.have_clip_region)
     921             :             {
     922           0 :                 if (!pixman_region32_intersect (&fill_region,
     923             :                                                 &fill_region,
     924             :                                                 &dest->common.clip_region))
     925           0 :                     return FALSE;
     926             :             }
     927             : 
     928           0 :             rects = pixman_region32_rectangles (&fill_region, &n_rects);
     929           0 :             for (j = 0; j < n_rects; ++j)
     930             :             {
     931           0 :                 const pixman_box32_t *rect = &(rects[j]);
     932           0 :                 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
     933           0 :                              rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
     934             :                              pixel);
     935             :             }
     936             : 
     937           0 :             pixman_region32_fini (&fill_region);
     938           0 :             return TRUE;
     939             :         }
     940             :     }
     941             : 
     942           0 :     solid = pixman_image_create_solid_fill (color);
     943           0 :     if (!solid)
     944           0 :         return FALSE;
     945             : 
     946           0 :     for (i = 0; i < n_boxes; ++i)
     947             :     {
     948           0 :         const pixman_box32_t *box = &(boxes[i]);
     949             : 
     950           0 :         pixman_image_composite32 (op, solid, NULL, dest,
     951             :                                   0, 0, 0, 0,
     952             :                                   box->x1, box->y1,
     953           0 :                                   box->x2 - box->x1, box->y2 - box->y1);
     954             :     }
     955             : 
     956           0 :     pixman_image_unref (solid);
     957             : 
     958           0 :     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           0 : pixman_version (void)
     982             : {
     983           0 :     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           0 : pixman_version_string (void)
     999             : {
    1000           0 :     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           0 : pixman_format_supported_source (pixman_format_code_t format)
    1015             : {
    1016           0 :     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           0 :         return TRUE;
    1076             : 
    1077             :     default:
    1078           0 :         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           0 : pixman_format_supported_destination (pixman_format_code_t format)
    1095             : {
    1096             :     /* YUV formats cannot be written to at the moment */
    1097           0 :     if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
    1098           0 :         return FALSE;
    1099             : 
    1100           0 :     return pixman_format_supported_source (format);
    1101             : }
    1102             : 
    1103             : PIXMAN_EXPORT pixman_bool_t
    1104           0 : 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           0 :     pixman_region32_init (&r32);
    1121             : 
    1122           0 :     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           0 :     if (retval)
    1128             :     {
    1129           0 :         if (!pixman_region16_copy_from_region32 (region, &r32))
    1130           0 :             retval = FALSE;
    1131             :     }
    1132             : 
    1133           0 :     pixman_region32_fini (&r32);
    1134           0 :     return retval;
    1135             : }

Generated by: LCOV version 1.13