Home | History | Annotate | Download | only in pixman
      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