1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/libpixman/src/pixman.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1135 @@ 1.4 +/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ 1.5 +/* 1.6 + * Copyright © 2000 SuSE, Inc. 1.7 + * Copyright © 2007 Red Hat, Inc. 1.8 + * 1.9 + * Permission to use, copy, modify, distribute, and sell this software and its 1.10 + * documentation for any purpose is hereby granted without fee, provided that 1.11 + * the above copyright notice appear in all copies and that both that 1.12 + * copyright notice and this permission notice appear in supporting 1.13 + * documentation, and that the name of SuSE not be used in advertising or 1.14 + * publicity pertaining to distribution of the software without specific, 1.15 + * written prior permission. SuSE makes no representations about the 1.16 + * suitability of this software for any purpose. It is provided "as is" 1.17 + * without express or implied warranty. 1.18 + * 1.19 + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 1.20 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 1.21 + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1.22 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1.23 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 1.24 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1.25 + * 1.26 + * Author: Keith Packard, SuSE, Inc. 1.27 + */ 1.28 + 1.29 +#ifdef HAVE_CONFIG_H 1.30 +#include <config.h> 1.31 +#endif 1.32 +#include "pixman-private.h" 1.33 + 1.34 +#include <stdlib.h> 1.35 + 1.36 +pixman_implementation_t *global_implementation; 1.37 + 1.38 +#ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR 1.39 +static void __attribute__((constructor)) 1.40 +pixman_constructor (void) 1.41 +{ 1.42 + global_implementation = _pixman_choose_implementation (); 1.43 +} 1.44 +#endif 1.45 + 1.46 +typedef struct operator_info_t operator_info_t; 1.47 + 1.48 +struct operator_info_t 1.49 +{ 1.50 + uint8_t opaque_info[4]; 1.51 +}; 1.52 + 1.53 +#define PACK(neither, src, dest, both) \ 1.54 + {{ (uint8_t)PIXMAN_OP_ ## neither, \ 1.55 + (uint8_t)PIXMAN_OP_ ## src, \ 1.56 + (uint8_t)PIXMAN_OP_ ## dest, \ 1.57 + (uint8_t)PIXMAN_OP_ ## both }} 1.58 + 1.59 +static const operator_info_t operator_table[] = 1.60 +{ 1.61 + /* Neither Opaque Src Opaque Dst Opaque Both Opaque */ 1.62 + PACK (CLEAR, CLEAR, CLEAR, CLEAR), 1.63 + PACK (SRC, SRC, SRC, SRC), 1.64 + PACK (DST, DST, DST, DST), 1.65 + PACK (OVER, SRC, OVER, SRC), 1.66 + PACK (OVER_REVERSE, OVER_REVERSE, DST, DST), 1.67 + PACK (IN, IN, SRC, SRC), 1.68 + PACK (IN_REVERSE, DST, IN_REVERSE, DST), 1.69 + PACK (OUT, OUT, CLEAR, CLEAR), 1.70 + PACK (OUT_REVERSE, CLEAR, OUT_REVERSE, CLEAR), 1.71 + PACK (ATOP, IN, OVER, SRC), 1.72 + PACK (ATOP_REVERSE, OVER_REVERSE, IN_REVERSE, DST), 1.73 + PACK (XOR, OUT, OUT_REVERSE, CLEAR), 1.74 + PACK (ADD, ADD, ADD, ADD), 1.75 + PACK (SATURATE, OVER_REVERSE, DST, DST), 1.76 + 1.77 + {{ 0 /* 0x0e */ }}, 1.78 + {{ 0 /* 0x0f */ }}, 1.79 + 1.80 + PACK (CLEAR, CLEAR, CLEAR, CLEAR), 1.81 + PACK (SRC, SRC, SRC, SRC), 1.82 + PACK (DST, DST, DST, DST), 1.83 + PACK (DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER), 1.84 + PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE), 1.85 + PACK (DISJOINT_IN, DISJOINT_IN, DISJOINT_IN, DISJOINT_IN), 1.86 + PACK (DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE), 1.87 + PACK (DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT), 1.88 + PACK (DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE), 1.89 + PACK (DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP), 1.90 + PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE), 1.91 + PACK (DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR), 1.92 + 1.93 + {{ 0 /* 0x1c */ }}, 1.94 + {{ 0 /* 0x1d */ }}, 1.95 + {{ 0 /* 0x1e */ }}, 1.96 + {{ 0 /* 0x1f */ }}, 1.97 + 1.98 + PACK (CLEAR, CLEAR, CLEAR, CLEAR), 1.99 + PACK (SRC, SRC, SRC, SRC), 1.100 + PACK (DST, DST, DST, DST), 1.101 + PACK (CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER), 1.102 + PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE), 1.103 + PACK (CONJOINT_IN, CONJOINT_IN, CONJOINT_IN, CONJOINT_IN), 1.104 + PACK (CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE), 1.105 + PACK (CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT), 1.106 + PACK (CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE), 1.107 + PACK (CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP), 1.108 + PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE), 1.109 + PACK (CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR), 1.110 + 1.111 + {{ 0 /* 0x2c */ }}, 1.112 + {{ 0 /* 0x2d */ }}, 1.113 + {{ 0 /* 0x2e */ }}, 1.114 + {{ 0 /* 0x2f */ }}, 1.115 + 1.116 + PACK (MULTIPLY, MULTIPLY, MULTIPLY, MULTIPLY), 1.117 + PACK (SCREEN, SCREEN, SCREEN, SCREEN), 1.118 + PACK (OVERLAY, OVERLAY, OVERLAY, OVERLAY), 1.119 + PACK (DARKEN, DARKEN, DARKEN, DARKEN), 1.120 + PACK (LIGHTEN, LIGHTEN, LIGHTEN, LIGHTEN), 1.121 + PACK (COLOR_DODGE, COLOR_DODGE, COLOR_DODGE, COLOR_DODGE), 1.122 + PACK (COLOR_BURN, COLOR_BURN, COLOR_BURN, COLOR_BURN), 1.123 + PACK (HARD_LIGHT, HARD_LIGHT, HARD_LIGHT, HARD_LIGHT), 1.124 + PACK (SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT), 1.125 + PACK (DIFFERENCE, DIFFERENCE, DIFFERENCE, DIFFERENCE), 1.126 + PACK (EXCLUSION, EXCLUSION, EXCLUSION, EXCLUSION), 1.127 + PACK (HSL_HUE, HSL_HUE, HSL_HUE, HSL_HUE), 1.128 + PACK (HSL_SATURATION, HSL_SATURATION, HSL_SATURATION, HSL_SATURATION), 1.129 + PACK (HSL_COLOR, HSL_COLOR, HSL_COLOR, HSL_COLOR), 1.130 + PACK (HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY), 1.131 +}; 1.132 + 1.133 +/* 1.134 + * Optimize the current operator based on opacity of source or destination 1.135 + * The output operator should be mathematically equivalent to the source. 1.136 + */ 1.137 +static pixman_op_t 1.138 +optimize_operator (pixman_op_t op, 1.139 + uint32_t src_flags, 1.140 + uint32_t mask_flags, 1.141 + uint32_t dst_flags) 1.142 +{ 1.143 + pixman_bool_t is_source_opaque, is_dest_opaque; 1.144 + 1.145 +#define OPAQUE_SHIFT 13 1.146 + 1.147 + COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT)); 1.148 + 1.149 + is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE); 1.150 + is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE); 1.151 + 1.152 + is_dest_opaque >>= OPAQUE_SHIFT - 1; 1.153 + is_source_opaque >>= OPAQUE_SHIFT; 1.154 + 1.155 + return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque]; 1.156 +} 1.157 + 1.158 +/* 1.159 + * Computing composite region 1.160 + */ 1.161 +static inline pixman_bool_t 1.162 +clip_general_image (pixman_region32_t * region, 1.163 + pixman_region32_t * clip, 1.164 + int dx, 1.165 + int dy) 1.166 +{ 1.167 + if (pixman_region32_n_rects (region) == 1 && 1.168 + pixman_region32_n_rects (clip) == 1) 1.169 + { 1.170 + pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL); 1.171 + pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL); 1.172 + int v; 1.173 + 1.174 + if (rbox->x1 < (v = cbox->x1 + dx)) 1.175 + rbox->x1 = v; 1.176 + if (rbox->x2 > (v = cbox->x2 + dx)) 1.177 + rbox->x2 = v; 1.178 + if (rbox->y1 < (v = cbox->y1 + dy)) 1.179 + rbox->y1 = v; 1.180 + if (rbox->y2 > (v = cbox->y2 + dy)) 1.181 + rbox->y2 = v; 1.182 + if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2) 1.183 + { 1.184 + pixman_region32_init (region); 1.185 + return FALSE; 1.186 + } 1.187 + } 1.188 + else if (!pixman_region32_not_empty (clip)) 1.189 + { 1.190 + return FALSE; 1.191 + } 1.192 + else 1.193 + { 1.194 + if (dx || dy) 1.195 + pixman_region32_translate (region, -dx, -dy); 1.196 + 1.197 + if (!pixman_region32_intersect (region, region, clip)) 1.198 + return FALSE; 1.199 + 1.200 + if (dx || dy) 1.201 + pixman_region32_translate (region, dx, dy); 1.202 + } 1.203 + 1.204 + return pixman_region32_not_empty (region); 1.205 +} 1.206 + 1.207 +static inline pixman_bool_t 1.208 +clip_source_image (pixman_region32_t * region, 1.209 + pixman_image_t * image, 1.210 + int dx, 1.211 + int dy) 1.212 +{ 1.213 + /* Source clips are ignored, unless they are explicitly turned on 1.214 + * and the clip in question was set by an X client. (Because if 1.215 + * the clip was not set by a client, then it is a hierarchy 1.216 + * clip and those should always be ignored for sources). 1.217 + */ 1.218 + if (!image->common.clip_sources || !image->common.client_clip) 1.219 + return TRUE; 1.220 + 1.221 + return clip_general_image (region, 1.222 + &image->common.clip_region, 1.223 + dx, dy); 1.224 +} 1.225 + 1.226 +/* 1.227 + * returns FALSE if the final region is empty. Indistinguishable from 1.228 + * an allocation failure, but rendering ignores those anyways. 1.229 + */ 1.230 +pixman_bool_t 1.231 +_pixman_compute_composite_region32 (pixman_region32_t * region, 1.232 + pixman_image_t * src_image, 1.233 + pixman_image_t * mask_image, 1.234 + pixman_image_t * dest_image, 1.235 + int32_t src_x, 1.236 + int32_t src_y, 1.237 + int32_t mask_x, 1.238 + int32_t mask_y, 1.239 + int32_t dest_x, 1.240 + int32_t dest_y, 1.241 + int32_t width, 1.242 + int32_t height) 1.243 +{ 1.244 + region->extents.x1 = dest_x; 1.245 + region->extents.x2 = dest_x + width; 1.246 + region->extents.y1 = dest_y; 1.247 + region->extents.y2 = dest_y + height; 1.248 + 1.249 + region->extents.x1 = MAX (region->extents.x1, 0); 1.250 + region->extents.y1 = MAX (region->extents.y1, 0); 1.251 + region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width); 1.252 + region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height); 1.253 + 1.254 + region->data = 0; 1.255 + 1.256 + /* Check for empty operation */ 1.257 + if (region->extents.x1 >= region->extents.x2 || 1.258 + region->extents.y1 >= region->extents.y2) 1.259 + { 1.260 + region->extents.x1 = 0; 1.261 + region->extents.x2 = 0; 1.262 + region->extents.y1 = 0; 1.263 + region->extents.y2 = 0; 1.264 + return FALSE; 1.265 + } 1.266 + 1.267 + if (dest_image->common.have_clip_region) 1.268 + { 1.269 + if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0)) 1.270 + return FALSE; 1.271 + } 1.272 + 1.273 + if (dest_image->common.alpha_map) 1.274 + { 1.275 + if (!pixman_region32_intersect_rect (region, region, 1.276 + dest_image->common.alpha_origin_x, 1.277 + dest_image->common.alpha_origin_y, 1.278 + dest_image->common.alpha_map->width, 1.279 + dest_image->common.alpha_map->height)) 1.280 + { 1.281 + return FALSE; 1.282 + } 1.283 + if (!pixman_region32_not_empty (region)) 1.284 + return FALSE; 1.285 + if (dest_image->common.alpha_map->common.have_clip_region) 1.286 + { 1.287 + if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region, 1.288 + -dest_image->common.alpha_origin_x, 1.289 + -dest_image->common.alpha_origin_y)) 1.290 + { 1.291 + return FALSE; 1.292 + } 1.293 + } 1.294 + } 1.295 + 1.296 + /* clip against src */ 1.297 + if (src_image->common.have_clip_region) 1.298 + { 1.299 + if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y)) 1.300 + return FALSE; 1.301 + } 1.302 + if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region) 1.303 + { 1.304 + if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map, 1.305 + dest_x - (src_x - src_image->common.alpha_origin_x), 1.306 + dest_y - (src_y - src_image->common.alpha_origin_y))) 1.307 + { 1.308 + return FALSE; 1.309 + } 1.310 + } 1.311 + /* clip against mask */ 1.312 + if (mask_image && mask_image->common.have_clip_region) 1.313 + { 1.314 + if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y)) 1.315 + return FALSE; 1.316 + 1.317 + if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region) 1.318 + { 1.319 + if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map, 1.320 + dest_x - (mask_x - mask_image->common.alpha_origin_x), 1.321 + dest_y - (mask_y - mask_image->common.alpha_origin_y))) 1.322 + { 1.323 + return FALSE; 1.324 + } 1.325 + } 1.326 + } 1.327 + 1.328 + return TRUE; 1.329 +} 1.330 + 1.331 +typedef struct 1.332 +{ 1.333 + pixman_fixed_48_16_t x1; 1.334 + pixman_fixed_48_16_t y1; 1.335 + pixman_fixed_48_16_t x2; 1.336 + pixman_fixed_48_16_t y2; 1.337 +} box_48_16_t; 1.338 + 1.339 +static pixman_bool_t 1.340 +compute_transformed_extents (pixman_transform_t *transform, 1.341 + const pixman_box32_t *extents, 1.342 + box_48_16_t *transformed) 1.343 +{ 1.344 + pixman_fixed_48_16_t tx1, ty1, tx2, ty2; 1.345 + pixman_fixed_t x1, y1, x2, y2; 1.346 + int i; 1.347 + 1.348 + x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2; 1.349 + y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2; 1.350 + x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2; 1.351 + y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2; 1.352 + 1.353 + if (!transform) 1.354 + { 1.355 + transformed->x1 = x1; 1.356 + transformed->y1 = y1; 1.357 + transformed->x2 = x2; 1.358 + transformed->y2 = y2; 1.359 + 1.360 + return TRUE; 1.361 + } 1.362 + 1.363 + tx1 = ty1 = INT64_MAX; 1.364 + tx2 = ty2 = INT64_MIN; 1.365 + 1.366 + for (i = 0; i < 4; ++i) 1.367 + { 1.368 + pixman_fixed_48_16_t tx, ty; 1.369 + pixman_vector_t v; 1.370 + 1.371 + v.vector[0] = (i & 0x01)? x1 : x2; 1.372 + v.vector[1] = (i & 0x02)? y1 : y2; 1.373 + v.vector[2] = pixman_fixed_1; 1.374 + 1.375 + if (!pixman_transform_point (transform, &v)) 1.376 + return FALSE; 1.377 + 1.378 + tx = (pixman_fixed_48_16_t)v.vector[0]; 1.379 + ty = (pixman_fixed_48_16_t)v.vector[1]; 1.380 + 1.381 + if (tx < tx1) 1.382 + tx1 = tx; 1.383 + if (ty < ty1) 1.384 + ty1 = ty; 1.385 + if (tx > tx2) 1.386 + tx2 = tx; 1.387 + if (ty > ty2) 1.388 + ty2 = ty; 1.389 + } 1.390 + 1.391 + transformed->x1 = tx1; 1.392 + transformed->y1 = ty1; 1.393 + transformed->x2 = tx2; 1.394 + transformed->y2 = ty2; 1.395 + 1.396 + return TRUE; 1.397 +} 1.398 + 1.399 +#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX)) 1.400 +#define ABS(f) (((f) < 0)? (-(f)) : (f)) 1.401 +#define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16))) 1.402 + 1.403 +static pixman_bool_t 1.404 +analyze_extent (pixman_image_t *image, 1.405 + const pixman_box32_t *extents, 1.406 + uint32_t *flags) 1.407 +{ 1.408 + pixman_transform_t *transform; 1.409 + pixman_fixed_t x_off, y_off; 1.410 + pixman_fixed_t width, height; 1.411 + pixman_fixed_t *params; 1.412 + box_48_16_t transformed; 1.413 + pixman_box32_t exp_extents; 1.414 + 1.415 + if (!image) 1.416 + return TRUE; 1.417 + 1.418 + /* Some compositing functions walk one step 1.419 + * outside the destination rectangle, so we 1.420 + * check here that the expanded-by-one source 1.421 + * extents in destination space fits in 16 bits 1.422 + */ 1.423 + if (!IS_16BIT (extents->x1 - 1) || 1.424 + !IS_16BIT (extents->y1 - 1) || 1.425 + !IS_16BIT (extents->x2 + 1) || 1.426 + !IS_16BIT (extents->y2 + 1)) 1.427 + { 1.428 + return FALSE; 1.429 + } 1.430 + 1.431 + transform = image->common.transform; 1.432 + if (image->common.type == BITS) 1.433 + { 1.434 + /* During repeat mode calculations we might convert the 1.435 + * width/height of an image to fixed 16.16, so we need 1.436 + * them to be smaller than 16 bits. 1.437 + */ 1.438 + if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff) 1.439 + return FALSE; 1.440 + 1.441 + if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM && 1.442 + extents->x1 >= 0 && 1.443 + extents->y1 >= 0 && 1.444 + extents->x2 <= image->bits.width && 1.445 + extents->y2 <= image->bits.height) 1.446 + { 1.447 + *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST; 1.448 + return TRUE; 1.449 + } 1.450 + 1.451 + switch (image->common.filter) 1.452 + { 1.453 + case PIXMAN_FILTER_CONVOLUTION: 1.454 + params = image->common.filter_params; 1.455 + x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1); 1.456 + y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1); 1.457 + width = params[0]; 1.458 + height = params[1]; 1.459 + break; 1.460 + 1.461 + case PIXMAN_FILTER_SEPARABLE_CONVOLUTION: 1.462 + params = image->common.filter_params; 1.463 + x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1); 1.464 + y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1); 1.465 + width = params[0]; 1.466 + height = params[1]; 1.467 + break; 1.468 + 1.469 + case PIXMAN_FILTER_GOOD: 1.470 + case PIXMAN_FILTER_BEST: 1.471 + case PIXMAN_FILTER_BILINEAR: 1.472 + x_off = - pixman_fixed_1 / 2; 1.473 + y_off = - pixman_fixed_1 / 2; 1.474 + width = pixman_fixed_1; 1.475 + height = pixman_fixed_1; 1.476 + break; 1.477 + 1.478 + case PIXMAN_FILTER_FAST: 1.479 + case PIXMAN_FILTER_NEAREST: 1.480 + x_off = - pixman_fixed_e; 1.481 + y_off = - pixman_fixed_e; 1.482 + width = 0; 1.483 + height = 0; 1.484 + break; 1.485 + 1.486 + default: 1.487 + return FALSE; 1.488 + } 1.489 + } 1.490 + else 1.491 + { 1.492 + x_off = 0; 1.493 + y_off = 0; 1.494 + width = 0; 1.495 + height = 0; 1.496 + } 1.497 + 1.498 + if (!compute_transformed_extents (transform, extents, &transformed)) 1.499 + return FALSE; 1.500 + 1.501 + /* Expand the source area by a tiny bit so account of different rounding that 1.502 + * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from 1.503 + * 0.5 so this won't cause the area computed to be overly pessimistic. 1.504 + */ 1.505 + transformed.x1 -= 8 * pixman_fixed_e; 1.506 + transformed.y1 -= 8 * pixman_fixed_e; 1.507 + transformed.x2 += 8 * pixman_fixed_e; 1.508 + transformed.y2 += 8 * pixman_fixed_e; 1.509 + 1.510 + if (image->common.type == BITS) 1.511 + { 1.512 + if (pixman_fixed_to_int (transformed.x1) >= 0 && 1.513 + pixman_fixed_to_int (transformed.y1) >= 0 && 1.514 + pixman_fixed_to_int (transformed.x2) < image->bits.width && 1.515 + pixman_fixed_to_int (transformed.y2) < image->bits.height) 1.516 + { 1.517 + *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST; 1.518 + } 1.519 + 1.520 + if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0 && 1.521 + pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0 && 1.522 + pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width && 1.523 + pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height) 1.524 + { 1.525 + *flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR; 1.526 + } 1.527 + } 1.528 + 1.529 + /* Check we don't overflow when the destination extents are expanded by one. 1.530 + * This ensures that compositing functions can simply walk the source space 1.531 + * using 16.16 variables without worrying about overflow. 1.532 + */ 1.533 + exp_extents = *extents; 1.534 + exp_extents.x1 -= 1; 1.535 + exp_extents.y1 -= 1; 1.536 + exp_extents.x2 += 1; 1.537 + exp_extents.y2 += 1; 1.538 + 1.539 + if (!compute_transformed_extents (transform, &exp_extents, &transformed)) 1.540 + return FALSE; 1.541 + 1.542 + if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e) || 1.543 + !IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e) || 1.544 + !IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width) || 1.545 + !IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height)) 1.546 + { 1.547 + return FALSE; 1.548 + } 1.549 + 1.550 + return TRUE; 1.551 +} 1.552 + 1.553 +/* 1.554 + * Work around GCC bug causing crashes in Mozilla with SSE2 1.555 + * 1.556 + * When using -msse, gcc generates movdqa instructions assuming that 1.557 + * the stack is 16 byte aligned. Unfortunately some applications, such 1.558 + * as Mozilla and Mono, end up aligning the stack to 4 bytes, which 1.559 + * causes the movdqa instructions to fail. 1.560 + * 1.561 + * The __force_align_arg_pointer__ makes gcc generate a prologue that 1.562 + * realigns the stack pointer to 16 bytes. 1.563 + * 1.564 + * On x86-64 this is not necessary because the standard ABI already 1.565 + * calls for a 16 byte aligned stack. 1.566 + * 1.567 + * See https://bugs.freedesktop.org/show_bug.cgi?id=15693 1.568 + */ 1.569 +#if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) 1.570 +__attribute__((__force_align_arg_pointer__)) 1.571 +#endif 1.572 +PIXMAN_EXPORT void 1.573 +pixman_image_composite32 (pixman_op_t op, 1.574 + pixman_image_t * src, 1.575 + pixman_image_t * mask, 1.576 + pixman_image_t * dest, 1.577 + int32_t src_x, 1.578 + int32_t src_y, 1.579 + int32_t mask_x, 1.580 + int32_t mask_y, 1.581 + int32_t dest_x, 1.582 + int32_t dest_y, 1.583 + int32_t width, 1.584 + int32_t height) 1.585 +{ 1.586 + pixman_format_code_t src_format, mask_format, dest_format; 1.587 + pixman_region32_t region; 1.588 + pixman_box32_t extents; 1.589 + pixman_implementation_t *imp; 1.590 + pixman_composite_func_t func; 1.591 + pixman_composite_info_t info; 1.592 + const pixman_box32_t *pbox; 1.593 + int n; 1.594 + 1.595 + _pixman_image_validate (src); 1.596 + if (mask) 1.597 + _pixman_image_validate (mask); 1.598 + _pixman_image_validate (dest); 1.599 + 1.600 + src_format = src->common.extended_format_code; 1.601 + info.src_flags = src->common.flags; 1.602 + 1.603 + if (mask && !(mask->common.flags & FAST_PATH_IS_OPAQUE)) 1.604 + { 1.605 + mask_format = mask->common.extended_format_code; 1.606 + info.mask_flags = mask->common.flags; 1.607 + } 1.608 + else 1.609 + { 1.610 + mask_format = PIXMAN_null; 1.611 + info.mask_flags = FAST_PATH_IS_OPAQUE; 1.612 + } 1.613 + 1.614 + dest_format = dest->common.extended_format_code; 1.615 + info.dest_flags = dest->common.flags; 1.616 + 1.617 + /* Check for pixbufs */ 1.618 + if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) && 1.619 + (src->type == BITS && src->bits.bits == mask->bits.bits) && 1.620 + (src->common.repeat == mask->common.repeat) && 1.621 + (info.src_flags & info.mask_flags & FAST_PATH_ID_TRANSFORM) && 1.622 + (src_x == mask_x && src_y == mask_y)) 1.623 + { 1.624 + if (src_format == PIXMAN_x8b8g8r8) 1.625 + src_format = mask_format = PIXMAN_pixbuf; 1.626 + else if (src_format == PIXMAN_x8r8g8b8) 1.627 + src_format = mask_format = PIXMAN_rpixbuf; 1.628 + } 1.629 + 1.630 + pixman_region32_init (®ion); 1.631 + 1.632 + if (!_pixman_compute_composite_region32 ( 1.633 + ®ion, src, mask, dest, 1.634 + src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height)) 1.635 + { 1.636 + goto out; 1.637 + } 1.638 + 1.639 + extents = *pixman_region32_extents (®ion); 1.640 + 1.641 + extents.x1 -= dest_x - src_x; 1.642 + extents.y1 -= dest_y - src_y; 1.643 + extents.x2 -= dest_x - src_x; 1.644 + extents.y2 -= dest_y - src_y; 1.645 + 1.646 + if (!analyze_extent (src, &extents, &info.src_flags)) 1.647 + goto out; 1.648 + 1.649 + extents.x1 -= src_x - mask_x; 1.650 + extents.y1 -= src_y - mask_y; 1.651 + extents.x2 -= src_x - mask_x; 1.652 + extents.y2 -= src_y - mask_y; 1.653 + 1.654 + if (!analyze_extent (mask, &extents, &info.mask_flags)) 1.655 + goto out; 1.656 + 1.657 + /* If the clip is within the source samples, and the samples are 1.658 + * opaque, then the source is effectively opaque. 1.659 + */ 1.660 +#define NEAREST_OPAQUE (FAST_PATH_SAMPLES_OPAQUE | \ 1.661 + FAST_PATH_NEAREST_FILTER | \ 1.662 + FAST_PATH_SAMPLES_COVER_CLIP_NEAREST) 1.663 +#define BILINEAR_OPAQUE (FAST_PATH_SAMPLES_OPAQUE | \ 1.664 + FAST_PATH_BILINEAR_FILTER | \ 1.665 + FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR) 1.666 + 1.667 + if ((info.src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE || 1.668 + (info.src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE) 1.669 + { 1.670 + info.src_flags |= FAST_PATH_IS_OPAQUE; 1.671 + } 1.672 + 1.673 + if ((info.mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE || 1.674 + (info.mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE) 1.675 + { 1.676 + info.mask_flags |= FAST_PATH_IS_OPAQUE; 1.677 + } 1.678 + 1.679 + /* 1.680 + * Check if we can replace our operator by a simpler one 1.681 + * if the src or dest are opaque. The output operator should be 1.682 + * mathematically equivalent to the source. 1.683 + */ 1.684 + info.op = optimize_operator (op, info.src_flags, info.mask_flags, info.dest_flags); 1.685 + 1.686 + _pixman_implementation_lookup_composite ( 1.687 + get_implementation (), info.op, 1.688 + src_format, info.src_flags, 1.689 + mask_format, info.mask_flags, 1.690 + dest_format, info.dest_flags, 1.691 + &imp, &func); 1.692 + 1.693 + info.src_image = src; 1.694 + info.mask_image = mask; 1.695 + info.dest_image = dest; 1.696 + 1.697 + pbox = pixman_region32_rectangles (®ion, &n); 1.698 + 1.699 + while (n--) 1.700 + { 1.701 + info.src_x = pbox->x1 + src_x - dest_x; 1.702 + info.src_y = pbox->y1 + src_y - dest_y; 1.703 + info.mask_x = pbox->x1 + mask_x - dest_x; 1.704 + info.mask_y = pbox->y1 + mask_y - dest_y; 1.705 + info.dest_x = pbox->x1; 1.706 + info.dest_y = pbox->y1; 1.707 + info.width = pbox->x2 - pbox->x1; 1.708 + info.height = pbox->y2 - pbox->y1; 1.709 + 1.710 + func (imp, &info); 1.711 + 1.712 + pbox++; 1.713 + } 1.714 + 1.715 +out: 1.716 + pixman_region32_fini (®ion); 1.717 +} 1.718 + 1.719 +PIXMAN_EXPORT void 1.720 +pixman_image_composite (pixman_op_t op, 1.721 + pixman_image_t * src, 1.722 + pixman_image_t * mask, 1.723 + pixman_image_t * dest, 1.724 + int16_t src_x, 1.725 + int16_t src_y, 1.726 + int16_t mask_x, 1.727 + int16_t mask_y, 1.728 + int16_t dest_x, 1.729 + int16_t dest_y, 1.730 + uint16_t width, 1.731 + uint16_t height) 1.732 +{ 1.733 + pixman_image_composite32 (op, src, mask, dest, src_x, src_y, 1.734 + mask_x, mask_y, dest_x, dest_y, width, height); 1.735 +} 1.736 + 1.737 +PIXMAN_EXPORT pixman_bool_t 1.738 +pixman_blt (uint32_t *src_bits, 1.739 + uint32_t *dst_bits, 1.740 + int src_stride, 1.741 + int dst_stride, 1.742 + int src_bpp, 1.743 + int dst_bpp, 1.744 + int src_x, 1.745 + int src_y, 1.746 + int dest_x, 1.747 + int dest_y, 1.748 + int width, 1.749 + int height) 1.750 +{ 1.751 + return _pixman_implementation_blt (get_implementation(), 1.752 + src_bits, dst_bits, src_stride, dst_stride, 1.753 + src_bpp, dst_bpp, 1.754 + src_x, src_y, 1.755 + dest_x, dest_y, 1.756 + width, height); 1.757 +} 1.758 + 1.759 +PIXMAN_EXPORT pixman_bool_t 1.760 +pixman_fill (uint32_t *bits, 1.761 + int stride, 1.762 + int bpp, 1.763 + int x, 1.764 + int y, 1.765 + int width, 1.766 + int height, 1.767 + uint32_t filler) 1.768 +{ 1.769 + return _pixman_implementation_fill ( 1.770 + get_implementation(), bits, stride, bpp, x, y, width, height, filler); 1.771 +} 1.772 + 1.773 +static uint32_t 1.774 +color_to_uint32 (const pixman_color_t *color) 1.775 +{ 1.776 + return 1.777 + (color->alpha >> 8 << 24) | 1.778 + (color->red >> 8 << 16) | 1.779 + (color->green & 0xff00) | 1.780 + (color->blue >> 8); 1.781 +} 1.782 + 1.783 +static pixman_bool_t 1.784 +color_to_pixel (const pixman_color_t *color, 1.785 + uint32_t * pixel, 1.786 + pixman_format_code_t format) 1.787 +{ 1.788 + uint32_t c = color_to_uint32 (color); 1.789 + 1.790 + if (!(format == PIXMAN_a8r8g8b8 || 1.791 + format == PIXMAN_x8r8g8b8 || 1.792 + format == PIXMAN_a8b8g8r8 || 1.793 + format == PIXMAN_x8b8g8r8 || 1.794 + format == PIXMAN_b8g8r8a8 || 1.795 + format == PIXMAN_b8g8r8x8 || 1.796 + format == PIXMAN_r8g8b8a8 || 1.797 + format == PIXMAN_r8g8b8x8 || 1.798 + format == PIXMAN_r5g6b5 || 1.799 + format == PIXMAN_b5g6r5 || 1.800 + format == PIXMAN_a8 || 1.801 + format == PIXMAN_a1)) 1.802 + { 1.803 + return FALSE; 1.804 + } 1.805 + 1.806 + if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR) 1.807 + { 1.808 + c = ((c & 0xff000000) >> 0) | 1.809 + ((c & 0x00ff0000) >> 16) | 1.810 + ((c & 0x0000ff00) >> 0) | 1.811 + ((c & 0x000000ff) << 16); 1.812 + } 1.813 + if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA) 1.814 + { 1.815 + c = ((c & 0xff000000) >> 24) | 1.816 + ((c & 0x00ff0000) >> 8) | 1.817 + ((c & 0x0000ff00) << 8) | 1.818 + ((c & 0x000000ff) << 24); 1.819 + } 1.820 + if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA) 1.821 + c = ((c & 0xff000000) >> 24) | (c << 8); 1.822 + 1.823 + if (format == PIXMAN_a1) 1.824 + c = c >> 31; 1.825 + else if (format == PIXMAN_a8) 1.826 + c = c >> 24; 1.827 + else if (format == PIXMAN_r5g6b5 || 1.828 + format == PIXMAN_b5g6r5) 1.829 + c = convert_8888_to_0565 (c); 1.830 + 1.831 +#if 0 1.832 + printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue); 1.833 + printf ("pixel: %x\n", c); 1.834 +#endif 1.835 + 1.836 + *pixel = c; 1.837 + return TRUE; 1.838 +} 1.839 + 1.840 +PIXMAN_EXPORT pixman_bool_t 1.841 +pixman_image_fill_rectangles (pixman_op_t op, 1.842 + pixman_image_t * dest, 1.843 + const pixman_color_t * color, 1.844 + int n_rects, 1.845 + const pixman_rectangle16_t *rects) 1.846 +{ 1.847 + pixman_box32_t stack_boxes[6]; 1.848 + pixman_box32_t *boxes; 1.849 + pixman_bool_t result; 1.850 + int i; 1.851 + 1.852 + if (n_rects > 6) 1.853 + { 1.854 + boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects); 1.855 + if (boxes == NULL) 1.856 + return FALSE; 1.857 + } 1.858 + else 1.859 + { 1.860 + boxes = stack_boxes; 1.861 + } 1.862 + 1.863 + for (i = 0; i < n_rects; ++i) 1.864 + { 1.865 + boxes[i].x1 = rects[i].x; 1.866 + boxes[i].y1 = rects[i].y; 1.867 + boxes[i].x2 = boxes[i].x1 + rects[i].width; 1.868 + boxes[i].y2 = boxes[i].y1 + rects[i].height; 1.869 + } 1.870 + 1.871 + result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes); 1.872 + 1.873 + if (boxes != stack_boxes) 1.874 + free (boxes); 1.875 + 1.876 + return result; 1.877 +} 1.878 + 1.879 +PIXMAN_EXPORT pixman_bool_t 1.880 +pixman_image_fill_boxes (pixman_op_t op, 1.881 + pixman_image_t * dest, 1.882 + const pixman_color_t *color, 1.883 + int n_boxes, 1.884 + const pixman_box32_t *boxes) 1.885 +{ 1.886 + pixman_image_t *solid; 1.887 + pixman_color_t c; 1.888 + int i; 1.889 + 1.890 + _pixman_image_validate (dest); 1.891 + 1.892 + if (color->alpha == 0xffff) 1.893 + { 1.894 + if (op == PIXMAN_OP_OVER) 1.895 + op = PIXMAN_OP_SRC; 1.896 + } 1.897 + 1.898 + if (op == PIXMAN_OP_CLEAR) 1.899 + { 1.900 + c.red = 0; 1.901 + c.green = 0; 1.902 + c.blue = 0; 1.903 + c.alpha = 0; 1.904 + 1.905 + color = &c; 1.906 + 1.907 + op = PIXMAN_OP_SRC; 1.908 + } 1.909 + 1.910 + if (op == PIXMAN_OP_SRC) 1.911 + { 1.912 + uint32_t pixel; 1.913 + 1.914 + if (color_to_pixel (color, &pixel, dest->bits.format)) 1.915 + { 1.916 + pixman_region32_t fill_region; 1.917 + int n_rects, j; 1.918 + pixman_box32_t *rects; 1.919 + 1.920 + if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes)) 1.921 + return FALSE; 1.922 + 1.923 + if (dest->common.have_clip_region) 1.924 + { 1.925 + if (!pixman_region32_intersect (&fill_region, 1.926 + &fill_region, 1.927 + &dest->common.clip_region)) 1.928 + return FALSE; 1.929 + } 1.930 + 1.931 + rects = pixman_region32_rectangles (&fill_region, &n_rects); 1.932 + for (j = 0; j < n_rects; ++j) 1.933 + { 1.934 + const pixman_box32_t *rect = &(rects[j]); 1.935 + pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format), 1.936 + rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1, 1.937 + pixel); 1.938 + } 1.939 + 1.940 + pixman_region32_fini (&fill_region); 1.941 + return TRUE; 1.942 + } 1.943 + } 1.944 + 1.945 + solid = pixman_image_create_solid_fill (color); 1.946 + if (!solid) 1.947 + return FALSE; 1.948 + 1.949 + for (i = 0; i < n_boxes; ++i) 1.950 + { 1.951 + const pixman_box32_t *box = &(boxes[i]); 1.952 + 1.953 + pixman_image_composite32 (op, solid, NULL, dest, 1.954 + 0, 0, 0, 0, 1.955 + box->x1, box->y1, 1.956 + box->x2 - box->x1, box->y2 - box->y1); 1.957 + } 1.958 + 1.959 + pixman_image_unref (solid); 1.960 + 1.961 + return TRUE; 1.962 +} 1.963 + 1.964 +/** 1.965 + * pixman_version: 1.966 + * 1.967 + * Returns the version of the pixman library encoded in a single 1.968 + * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that 1.969 + * later versions compare greater than earlier versions. 1.970 + * 1.971 + * A run-time comparison to check that pixman's version is greater than 1.972 + * or equal to version X.Y.Z could be performed as follows: 1.973 + * 1.974 + * <informalexample><programlisting> 1.975 + * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...} 1.976 + * </programlisting></informalexample> 1.977 + * 1.978 + * See also pixman_version_string() as well as the compile-time 1.979 + * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING. 1.980 + * 1.981 + * Return value: the encoded version. 1.982 + **/ 1.983 +PIXMAN_EXPORT int 1.984 +pixman_version (void) 1.985 +{ 1.986 + return PIXMAN_VERSION; 1.987 +} 1.988 + 1.989 +/** 1.990 + * pixman_version_string: 1.991 + * 1.992 + * Returns the version of the pixman library as a human-readable string 1.993 + * of the form "X.Y.Z". 1.994 + * 1.995 + * See also pixman_version() as well as the compile-time equivalents 1.996 + * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION. 1.997 + * 1.998 + * Return value: a string containing the version. 1.999 + **/ 1.1000 +PIXMAN_EXPORT const char* 1.1001 +pixman_version_string (void) 1.1002 +{ 1.1003 + return PIXMAN_VERSION_STRING; 1.1004 +} 1.1005 + 1.1006 +/** 1.1007 + * pixman_format_supported_source: 1.1008 + * @format: A pixman_format_code_t format 1.1009 + * 1.1010 + * Return value: whether the provided format code is a supported 1.1011 + * format for a pixman surface used as a source in 1.1012 + * rendering. 1.1013 + * 1.1014 + * Currently, all pixman_format_code_t values are supported. 1.1015 + **/ 1.1016 +PIXMAN_EXPORT pixman_bool_t 1.1017 +pixman_format_supported_source (pixman_format_code_t format) 1.1018 +{ 1.1019 + switch (format) 1.1020 + { 1.1021 + /* 32 bpp formats */ 1.1022 + case PIXMAN_a2b10g10r10: 1.1023 + case PIXMAN_x2b10g10r10: 1.1024 + case PIXMAN_a2r10g10b10: 1.1025 + case PIXMAN_x2r10g10b10: 1.1026 + case PIXMAN_a8r8g8b8: 1.1027 + case PIXMAN_a8r8g8b8_sRGB: 1.1028 + case PIXMAN_x8r8g8b8: 1.1029 + case PIXMAN_a8b8g8r8: 1.1030 + case PIXMAN_x8b8g8r8: 1.1031 + case PIXMAN_b8g8r8a8: 1.1032 + case PIXMAN_b8g8r8x8: 1.1033 + case PIXMAN_r8g8b8a8: 1.1034 + case PIXMAN_r8g8b8x8: 1.1035 + case PIXMAN_r8g8b8: 1.1036 + case PIXMAN_b8g8r8: 1.1037 + case PIXMAN_r5g6b5: 1.1038 + case PIXMAN_b5g6r5: 1.1039 + case PIXMAN_x14r6g6b6: 1.1040 + /* 16 bpp formats */ 1.1041 + case PIXMAN_a1r5g5b5: 1.1042 + case PIXMAN_x1r5g5b5: 1.1043 + case PIXMAN_a1b5g5r5: 1.1044 + case PIXMAN_x1b5g5r5: 1.1045 + case PIXMAN_a4r4g4b4: 1.1046 + case PIXMAN_x4r4g4b4: 1.1047 + case PIXMAN_a4b4g4r4: 1.1048 + case PIXMAN_x4b4g4r4: 1.1049 + /* 8bpp formats */ 1.1050 + case PIXMAN_a8: 1.1051 + case PIXMAN_r3g3b2: 1.1052 + case PIXMAN_b2g3r3: 1.1053 + case PIXMAN_a2r2g2b2: 1.1054 + case PIXMAN_a2b2g2r2: 1.1055 + case PIXMAN_c8: 1.1056 + case PIXMAN_g8: 1.1057 + case PIXMAN_x4a4: 1.1058 + /* Collides with PIXMAN_c8 1.1059 + case PIXMAN_x4c4: 1.1060 + */ 1.1061 + /* Collides with PIXMAN_g8 1.1062 + case PIXMAN_x4g4: 1.1063 + */ 1.1064 + /* 4bpp formats */ 1.1065 + case PIXMAN_a4: 1.1066 + case PIXMAN_r1g2b1: 1.1067 + case PIXMAN_b1g2r1: 1.1068 + case PIXMAN_a1r1g1b1: 1.1069 + case PIXMAN_a1b1g1r1: 1.1070 + case PIXMAN_c4: 1.1071 + case PIXMAN_g4: 1.1072 + /* 1bpp formats */ 1.1073 + case PIXMAN_a1: 1.1074 + case PIXMAN_g1: 1.1075 + /* YUV formats */ 1.1076 + case PIXMAN_yuy2: 1.1077 + case PIXMAN_yv12: 1.1078 + return TRUE; 1.1079 + 1.1080 + default: 1.1081 + return FALSE; 1.1082 + } 1.1083 +} 1.1084 + 1.1085 +/** 1.1086 + * pixman_format_supported_destination: 1.1087 + * @format: A pixman_format_code_t format 1.1088 + * 1.1089 + * Return value: whether the provided format code is a supported 1.1090 + * format for a pixman surface used as a destination in 1.1091 + * rendering. 1.1092 + * 1.1093 + * Currently, all pixman_format_code_t values are supported 1.1094 + * except for the YUV formats. 1.1095 + **/ 1.1096 +PIXMAN_EXPORT pixman_bool_t 1.1097 +pixman_format_supported_destination (pixman_format_code_t format) 1.1098 +{ 1.1099 + /* YUV formats cannot be written to at the moment */ 1.1100 + if (format == PIXMAN_yuy2 || format == PIXMAN_yv12) 1.1101 + return FALSE; 1.1102 + 1.1103 + return pixman_format_supported_source (format); 1.1104 +} 1.1105 + 1.1106 +PIXMAN_EXPORT pixman_bool_t 1.1107 +pixman_compute_composite_region (pixman_region16_t * region, 1.1108 + pixman_image_t * src_image, 1.1109 + pixman_image_t * mask_image, 1.1110 + pixman_image_t * dest_image, 1.1111 + int16_t src_x, 1.1112 + int16_t src_y, 1.1113 + int16_t mask_x, 1.1114 + int16_t mask_y, 1.1115 + int16_t dest_x, 1.1116 + int16_t dest_y, 1.1117 + uint16_t width, 1.1118 + uint16_t height) 1.1119 +{ 1.1120 + pixman_region32_t r32; 1.1121 + pixman_bool_t retval; 1.1122 + 1.1123 + pixman_region32_init (&r32); 1.1124 + 1.1125 + retval = _pixman_compute_composite_region32 ( 1.1126 + &r32, src_image, mask_image, dest_image, 1.1127 + src_x, src_y, mask_x, mask_y, dest_x, dest_y, 1.1128 + width, height); 1.1129 + 1.1130 + if (retval) 1.1131 + { 1.1132 + if (!pixman_region16_copy_from_region32 (region, &r32)) 1.1133 + retval = FALSE; 1.1134 + } 1.1135 + 1.1136 + pixman_region32_fini (&r32); 1.1137 + return retval; 1.1138 +}