1 /* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
3 * Copyright © 2000 SuSE, Inc.
4 * Copyright © 2007 Red Hat, Inc.
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.
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.
23 * Author: Keith Packard, SuSE, Inc.
29 #include "pixman-private.h"
33 pixman_implementation_t *global_implementation;
35 #ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
36 static void __attribute__((constructor))
37 pixman_constructor (void)
39 global_implementation = _pixman_choose_implementation ();
43 typedef struct operator_info_t operator_info_t;
45 struct operator_info_t
47 uint8_t opaque_info[4];
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 }}
56 static const operator_info_t operator_table[] =
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),
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),
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),
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),
131 * Optimize the current operator based on opacity of source or destination
132 * The output operator should be mathematically equivalent to the source.
135 optimize_operator (pixman_op_t op,
140 pixman_bool_t is_source_opaque, is_dest_opaque;
142 #define OPAQUE_SHIFT 13
144 COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
146 is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
147 is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
149 is_dest_opaque >>= OPAQUE_SHIFT - 1;
150 is_source_opaque >>= OPAQUE_SHIFT;
152 return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
156 * Computing composite region
158 static inline pixman_bool_t
159 clip_general_image (pixman_region32_t * region,
160 pixman_region32_t * clip,
164 if (pixman_region32_n_rects (region) == 1 &&
165 pixman_region32_n_rects (clip) == 1)
167 pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
168 pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
171 if (rbox->x1 < (v = cbox->x1 + dx))
173 if (rbox->x2 > (v = cbox->x2 + dx))
175 if (rbox->y1 < (v = cbox->y1 + dy))
177 if (rbox->y2 > (v = cbox->y2 + dy))
179 if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
181 pixman_region32_init (region);
185 else if (!pixman_region32_not_empty (clip))
192 pixman_region32_translate (region, -dx, -dy);
194 if (!pixman_region32_intersect (region, region, clip))
198 pixman_region32_translate (region, dx, dy);
201 return pixman_region32_not_empty (region);
204 static inline pixman_bool_t
205 clip_source_image (pixman_region32_t * region,
206 pixman_image_t * image,
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).
215 if (!image->common.clip_sources || !image->common.client_clip)
218 return clip_general_image (region,
219 &image->common.clip_region,
224 * returns FALSE if the final region is empty. Indistinguishable from
225 * an allocation failure, but rendering ignores those anyways.
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,
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;
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);
253 /* Check for empty operation */
254 if (region->extents.x1 >= region->extents.x2 ||
255 region->extents.y1 >= region->extents.y2)
257 region->extents.x1 = 0;
258 region->extents.x2 = 0;
259 region->extents.y1 = 0;
260 region->extents.y2 = 0;
264 if (dest_image->common.have_clip_region)
266 if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
270 if (dest_image->common.alpha_map)
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))
280 if (!pixman_region32_not_empty (region))
282 if (dest_image->common.alpha_map->common.have_clip_region)
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))
293 /* clip against src */
294 if (src_image->common.have_clip_region)
296 if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
299 if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
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)))
308 /* clip against mask */
309 if (mask_image && mask_image->common.have_clip_region)
311 if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
314 if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
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)))
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;
337 compute_transformed_extents (pixman_transform_t *transform,
338 const pixman_box32_t *extents,
339 box_48_16_t *transformed)
341 pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
342 pixman_fixed_t x1, y1, x2, y2;
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;
352 transformed->x1 = x1;
353 transformed->y1 = y1;
354 transformed->x2 = x2;
355 transformed->y2 = y2;
360 tx1 = ty1 = INT64_MAX;
361 tx2 = ty2 = INT64_MIN;
363 for (i = 0; i < 4; ++i)
365 pixman_fixed_48_16_t tx, ty;
368 v.vector[0] = (i & 0x01)? x1 : x2;
369 v.vector[1] = (i & 0x02)? y1 : y2;
370 v.vector[2] = pixman_fixed_1;
372 if (!pixman_transform_point (transform, &v))
375 tx = (pixman_fixed_48_16_t)v.vector[0];
376 ty = (pixman_fixed_48_16_t)v.vector[1];
388 transformed->x1 = tx1;
389 transformed->y1 = ty1;
390 transformed->x2 = tx2;
391 transformed->y2 = ty2;
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)))
401 analyze_extent (pixman_image_t *image,
402 const pixman_box32_t *extents,
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;
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
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))
428 transform = image->common.transform;
429 if (image->common.type == BITS)
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.
435 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
438 if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM &&
441 extents->x2 <= image->bits.width &&
442 extents->y2 <= image->bits.height)
444 *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
448 switch (image->common.filter)
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);
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);
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;
475 case PIXMAN_FILTER_FAST:
476 case PIXMAN_FILTER_NEAREST:
477 x_off = - pixman_fixed_e;
478 y_off = - pixman_fixed_e;
495 if (!compute_transformed_extents (transform, extents, &transformed))
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.
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;
507 if (image->common.type == BITS)
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)
514 *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
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)
522 *flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR;
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.
530 exp_extents = *extents;
536 if (!compute_transformed_extents (transform, &exp_extents, &transformed))
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))
551 * Work around GCC bug causing crashes in Mozilla with SSE2
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.
558 * The __force_align_arg_pointer__ makes gcc generate a prologue that
559 * realigns the stack pointer to 16 bytes.
561 * On x86-64 this is not necessary because the standard ABI already
562 * calls for a 16 byte aligned stack.
564 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
566 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
567 __attribute__((__force_align_arg_pointer__))
570 pixman_image_composite32 (pixman_op_t op,
571 pixman_image_t * src,
572 pixman_image_t * mask,
573 pixman_image_t * dest,
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;
592 _pixman_image_validate (src);
594 _pixman_image_validate (mask);
595 _pixman_image_validate (dest);
597 src_format = src->common.extended_format_code;
598 info.src_flags = src->common.flags;
600 if (mask && !(mask->common.flags & FAST_PATH_IS_OPAQUE))
602 mask_format = mask->common.extended_format_code;
603 info.mask_flags = mask->common.flags;
607 mask_format = PIXMAN_null;
608 info.mask_flags = FAST_PATH_IS_OPAQUE | FAST_PATH_NO_ALPHA_MAP;
611 dest_format = dest->common.extended_format_code;
612 info.dest_flags = dest->common.flags;
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))
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;
627 pixman_region32_init (®ion);
629 if (!_pixman_compute_composite_region32 (
630 ®ion, src, mask, dest,
631 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
636 extents = *pixman_region32_extents (®ion);
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;
643 if (!analyze_extent (src, &extents, &info.src_flags))
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;
651 if (!analyze_extent (mask, &extents, &info.mask_flags))
654 /* If the clip is within the source samples, and the samples are
655 * opaque, then the source is effectively opaque.
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)
664 if ((info.src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
665 (info.src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
667 info.src_flags |= FAST_PATH_IS_OPAQUE;
670 if ((info.mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
671 (info.mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
673 info.mask_flags |= FAST_PATH_IS_OPAQUE;
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.
681 info.op = optimize_operator (op, info.src_flags, info.mask_flags, info.dest_flags);
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,
690 info.src_image = src;
691 info.mask_image = mask;
692 info.dest_image = dest;
694 pbox = pixman_region32_rectangles (®ion, &n);
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;
713 pixman_region32_fini (®ion);
717 pixman_image_composite (pixman_op_t op,
718 pixman_image_t * src,
719 pixman_image_t * mask,
720 pixman_image_t * dest,
730 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
731 mask_x, mask_y, dest_x, dest_y, width, height);
734 PIXMAN_EXPORT pixman_bool_t
735 pixman_blt (uint32_t *src_bits,
748 return _pixman_implementation_blt (get_implementation(),
749 src_bits, dst_bits, src_stride, dst_stride,
756 PIXMAN_EXPORT pixman_bool_t
757 pixman_fill (uint32_t *bits,
766 return _pixman_implementation_fill (
767 get_implementation(), bits, stride, bpp, x, y, width, height, filler);
771 color_to_uint32 (const pixman_color_t *color)
774 (color->alpha >> 8 << 24) |
775 (color->red >> 8 << 16) |
776 (color->green & 0xff00) |
781 color_to_pixel (const pixman_color_t *color,
783 pixman_format_code_t format)
785 uint32_t c = color_to_uint32 (color);
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))
803 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
805 c = ((c & 0xff000000) >> 0) |
806 ((c & 0x00ff0000) >> 16) |
807 ((c & 0x0000ff00) >> 0) |
808 ((c & 0x000000ff) << 16);
810 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
812 c = ((c & 0xff000000) >> 24) |
813 ((c & 0x00ff0000) >> 8) |
814 ((c & 0x0000ff00) << 8) |
815 ((c & 0x000000ff) << 24);
817 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA)
818 c = ((c & 0xff000000) >> 24) | (c << 8);
820 if (format == PIXMAN_a1)
822 else if (format == PIXMAN_a8)
824 else if (format == PIXMAN_r5g6b5 ||
825 format == PIXMAN_b5g6r5)
826 c = convert_8888_to_0565 (c);
829 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
830 printf ("pixel: %x\n", c);
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,
842 const pixman_rectangle16_t *rects)
844 pixman_box32_t stack_boxes[6];
845 pixman_box32_t *boxes;
846 pixman_bool_t result;
851 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
860 for (i = 0; i < n_rects; ++i)
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;
868 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
870 if (boxes != stack_boxes)
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,
881 const pixman_box32_t *boxes)
883 pixman_image_t *solid;
887 _pixman_image_validate (dest);
889 if (color->alpha == 0xffff)
891 if (op == PIXMAN_OP_OVER)
895 if (op == PIXMAN_OP_CLEAR)
907 if (op == PIXMAN_OP_SRC)
911 if (color_to_pixel (color, &pixel, dest->bits.format))
913 pixman_region32_t fill_region;
915 pixman_box32_t *rects;
917 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
920 if (dest->common.have_clip_region)
922 if (!pixman_region32_intersect (&fill_region,
924 &dest->common.clip_region))
928 rects = pixman_region32_rectangles (&fill_region, &n_rects);
929 for (j = 0; j < n_rects; ++j)
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,
937 pixman_region32_fini (&fill_region);
942 solid = pixman_image_create_solid_fill (color);
946 for (i = 0; i < n_boxes; ++i)
948 const pixman_box32_t *box = &(boxes[i]);
950 pixman_image_composite32 (op, solid, NULL, dest,
953 box->x2 - box->x1, box->y2 - box->y1);
956 pixman_image_unref (solid);
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.
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:
971 * <informalexample><programlisting>
972 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
973 * </programlisting></informalexample>
975 * See also pixman_version_string() as well as the compile-time
976 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
978 * Return value: the encoded version.
981 pixman_version (void)
983 return PIXMAN_VERSION;
987 * pixman_version_string:
989 * Returns the version of the pixman library as a human-readable string
990 * of the form "X.Y.Z".
992 * See also pixman_version() as well as the compile-time equivalents
993 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
995 * Return value: a string containing the version.
997 PIXMAN_EXPORT const char*
998 pixman_version_string (void)
1000 return PIXMAN_VERSION_STRING;
1004 * pixman_format_supported_source:
1005 * @format: A pixman_format_code_t format
1007 * Return value: whether the provided format code is a supported
1008 * format for a pixman surface used as a source in
1011 * Currently, all pixman_format_code_t values are supported.
1013 PIXMAN_EXPORT pixman_bool_t
1014 pixman_format_supported_source (pixman_format_code_t format)
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:
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:
1050 case PIXMAN_a2r2g2b2:
1051 case PIXMAN_a2b2g2r2:
1055 /* Collides with PIXMAN_c8
1058 /* Collides with PIXMAN_g8
1065 case PIXMAN_a1r1g1b1:
1066 case PIXMAN_a1b1g1r1:
1083 * pixman_format_supported_destination:
1084 * @format: A pixman_format_code_t format
1086 * Return value: whether the provided format code is a supported
1087 * format for a pixman surface used as a destination in
1090 * Currently, all pixman_format_code_t values are supported
1091 * except for the YUV formats.
1093 PIXMAN_EXPORT pixman_bool_t
1094 pixman_format_supported_destination (pixman_format_code_t format)
1096 /* YUV formats cannot be written to at the moment */
1097 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1100 return pixman_format_supported_source (format);
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,
1117 pixman_region32_t r32;
1118 pixman_bool_t retval;
1120 pixman_region32_init (&r32);
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,
1129 if (!pixman_region16_copy_from_region32 (region, &r32))
1133 pixman_region32_fini (&r32);