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 static 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 static force_inline pixman_implementation_t *
44 get_implementation (void)
46 #ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
47 if (!global_implementation)
48 global_implementation = _pixman_choose_implementation ();
50 return global_implementation;
53 typedef struct operator_info_t operator_info_t;
55 struct operator_info_t
57 uint8_t opaque_info[4];
60 #define PACK(neither, src, dest, both) \
61 {{ (uint8_t)PIXMAN_OP_ ## neither, \
62 (uint8_t)PIXMAN_OP_ ## src, \
63 (uint8_t)PIXMAN_OP_ ## dest, \
64 (uint8_t)PIXMAN_OP_ ## both }}
66 static const operator_info_t operator_table[] =
68 /* Neither Opaque Src Opaque Dst Opaque Both Opaque */
69 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
70 PACK (SRC, SRC, SRC, SRC),
71 PACK (DST, DST, DST, DST),
72 PACK (OVER, SRC, OVER, SRC),
73 PACK (OVER_REVERSE, OVER_REVERSE, DST, DST),
74 PACK (IN, IN, SRC, SRC),
75 PACK (IN_REVERSE, DST, IN_REVERSE, DST),
76 PACK (OUT, OUT, CLEAR, CLEAR),
77 PACK (OUT_REVERSE, CLEAR, OUT_REVERSE, CLEAR),
78 PACK (ATOP, IN, OVER, SRC),
79 PACK (ATOP_REVERSE, OVER_REVERSE, IN_REVERSE, DST),
80 PACK (XOR, OUT, OUT_REVERSE, CLEAR),
81 PACK (ADD, ADD, ADD, ADD),
82 PACK (SATURATE, OVER_REVERSE, DST, DST),
87 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
88 PACK (SRC, SRC, SRC, SRC),
89 PACK (DST, DST, DST, DST),
90 PACK (DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER),
91 PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
92 PACK (DISJOINT_IN, DISJOINT_IN, DISJOINT_IN, DISJOINT_IN),
93 PACK (DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE),
94 PACK (DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT),
95 PACK (DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE),
96 PACK (DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP),
97 PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
98 PACK (DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR),
105 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
106 PACK (SRC, SRC, SRC, SRC),
107 PACK (DST, DST, DST, DST),
108 PACK (CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER),
109 PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
110 PACK (CONJOINT_IN, CONJOINT_IN, CONJOINT_IN, CONJOINT_IN),
111 PACK (CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE),
112 PACK (CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT),
113 PACK (CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE),
114 PACK (CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP),
115 PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
116 PACK (CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR),
123 PACK (MULTIPLY, MULTIPLY, MULTIPLY, MULTIPLY),
124 PACK (SCREEN, SCREEN, SCREEN, SCREEN),
125 PACK (OVERLAY, OVERLAY, OVERLAY, OVERLAY),
126 PACK (DARKEN, DARKEN, DARKEN, DARKEN),
127 PACK (LIGHTEN, LIGHTEN, LIGHTEN, LIGHTEN),
128 PACK (COLOR_DODGE, COLOR_DODGE, COLOR_DODGE, COLOR_DODGE),
129 PACK (COLOR_BURN, COLOR_BURN, COLOR_BURN, COLOR_BURN),
130 PACK (HARD_LIGHT, HARD_LIGHT, HARD_LIGHT, HARD_LIGHT),
131 PACK (SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT),
132 PACK (DIFFERENCE, DIFFERENCE, DIFFERENCE, DIFFERENCE),
133 PACK (EXCLUSION, EXCLUSION, EXCLUSION, EXCLUSION),
134 PACK (HSL_HUE, HSL_HUE, HSL_HUE, HSL_HUE),
135 PACK (HSL_SATURATION, HSL_SATURATION, HSL_SATURATION, HSL_SATURATION),
136 PACK (HSL_COLOR, HSL_COLOR, HSL_COLOR, HSL_COLOR),
137 PACK (HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY),
141 * Optimize the current operator based on opacity of source or destination
142 * The output operator should be mathematically equivalent to the source.
145 optimize_operator (pixman_op_t op,
150 pixman_bool_t is_source_opaque, is_dest_opaque;
152 #define OPAQUE_SHIFT 13
154 COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
156 is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
157 is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
159 is_dest_opaque >>= OPAQUE_SHIFT - 1;
160 is_source_opaque >>= OPAQUE_SHIFT;
162 return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
166 * Computing composite region
168 static inline pixman_bool_t
169 clip_general_image (pixman_region32_t * region,
170 pixman_region32_t * clip,
174 if (pixman_region32_n_rects (region) == 1 &&
175 pixman_region32_n_rects (clip) == 1)
177 pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
178 pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
181 if (rbox->x1 < (v = cbox->x1 + dx))
183 if (rbox->x2 > (v = cbox->x2 + dx))
185 if (rbox->y1 < (v = cbox->y1 + dy))
187 if (rbox->y2 > (v = cbox->y2 + dy))
189 if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
191 pixman_region32_init (region);
195 else if (!pixman_region32_not_empty (clip))
202 pixman_region32_translate (region, -dx, -dy);
204 if (!pixman_region32_intersect (region, region, clip))
208 pixman_region32_translate (region, dx, dy);
211 return pixman_region32_not_empty (region);
214 static inline pixman_bool_t
215 clip_source_image (pixman_region32_t * region,
216 pixman_image_t * image,
220 /* Source clips are ignored, unless they are explicitly turned on
221 * and the clip in question was set by an X client. (Because if
222 * the clip was not set by a client, then it is a hierarchy
223 * clip and those should always be ignored for sources).
225 if (!image->common.clip_sources || !image->common.client_clip)
228 return clip_general_image (region,
229 &image->common.clip_region,
234 * returns FALSE if the final region is empty. Indistinguishable from
235 * an allocation failure, but rendering ignores those anyways.
238 pixman_compute_composite_region32 (pixman_region32_t * region,
239 pixman_image_t * src_image,
240 pixman_image_t * mask_image,
241 pixman_image_t * dest_image,
251 region->extents.x1 = dest_x;
252 region->extents.x2 = dest_x + width;
253 region->extents.y1 = dest_y;
254 region->extents.y2 = dest_y + height;
256 region->extents.x1 = MAX (region->extents.x1, 0);
257 region->extents.y1 = MAX (region->extents.y1, 0);
258 region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width);
259 region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height);
263 /* Check for empty operation */
264 if (region->extents.x1 >= region->extents.x2 ||
265 region->extents.y1 >= region->extents.y2)
267 region->extents.x1 = 0;
268 region->extents.x2 = 0;
269 region->extents.y1 = 0;
270 region->extents.y2 = 0;
274 if (dest_image->common.have_clip_region)
276 if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
280 if (dest_image->common.alpha_map)
282 if (!pixman_region32_intersect_rect (region, region,
283 dest_image->common.alpha_origin_x,
284 dest_image->common.alpha_origin_y,
285 dest_image->common.alpha_map->width,
286 dest_image->common.alpha_map->height))
290 if (!pixman_region32_not_empty (region))
292 if (dest_image->common.alpha_map->common.have_clip_region)
294 if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region,
295 -dest_image->common.alpha_origin_x,
296 -dest_image->common.alpha_origin_y))
303 /* clip against src */
304 if (src_image->common.have_clip_region)
306 if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
309 if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
311 if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
312 dest_x - (src_x - src_image->common.alpha_origin_x),
313 dest_y - (src_y - src_image->common.alpha_origin_y)))
318 /* clip against mask */
319 if (mask_image && mask_image->common.have_clip_region)
321 if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
324 if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
326 if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
327 dest_x - (mask_x - mask_image->common.alpha_origin_x),
328 dest_y - (mask_y - mask_image->common.alpha_origin_y)))
340 pixman_fixed_48_16_t x1;
341 pixman_fixed_48_16_t y1;
342 pixman_fixed_48_16_t x2;
343 pixman_fixed_48_16_t y2;
347 compute_transformed_extents (pixman_transform_t *transform,
348 const pixman_box32_t *extents,
349 box_48_16_t *transformed)
351 pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
352 pixman_fixed_t x1, y1, x2, y2;
355 x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
356 y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
357 x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
358 y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
362 transformed->x1 = x1;
363 transformed->y1 = y1;
364 transformed->x2 = x2;
365 transformed->y2 = y2;
370 tx1 = ty1 = INT64_MAX;
371 tx2 = ty2 = INT64_MIN;
373 for (i = 0; i < 4; ++i)
375 pixman_fixed_48_16_t tx, ty;
378 v.vector[0] = (i & 0x01)? x1 : x2;
379 v.vector[1] = (i & 0x02)? y1 : y2;
380 v.vector[2] = pixman_fixed_1;
382 if (!pixman_transform_point (transform, &v))
385 tx = (pixman_fixed_48_16_t)v.vector[0];
386 ty = (pixman_fixed_48_16_t)v.vector[1];
398 transformed->x1 = tx1;
399 transformed->y1 = ty1;
400 transformed->x2 = tx2;
401 transformed->y2 = ty2;
406 #define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
407 #define ABS(f) (((f) < 0)? (-(f)) : (f))
408 #define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16)))
411 analyze_extent (pixman_image_t *image,
412 const pixman_box32_t *extents,
415 pixman_transform_t *transform;
416 pixman_fixed_t x_off, y_off;
417 pixman_fixed_t width, height;
418 pixman_fixed_t *params;
419 box_48_16_t transformed;
420 pixman_box32_t exp_extents;
425 /* Some compositing functions walk one step
426 * outside the destination rectangle, so we
427 * check here that the expanded-by-one source
428 * extents in destination space fits in 16 bits
430 if (!IS_16BIT (extents->x1 - 1) ||
431 !IS_16BIT (extents->y1 - 1) ||
432 !IS_16BIT (extents->x2 + 1) ||
433 !IS_16BIT (extents->y2 + 1))
438 transform = image->common.transform;
439 if (image->common.type == BITS)
441 /* During repeat mode calculations we might convert the
442 * width/height of an image to fixed 16.16, so we need
443 * them to be smaller than 16 bits.
445 if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
448 if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM &&
451 extents->x2 <= image->bits.width &&
452 extents->y2 <= image->bits.height)
454 *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
458 switch (image->common.filter)
460 case PIXMAN_FILTER_CONVOLUTION:
461 params = image->common.filter_params;
462 x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
463 y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
468 case PIXMAN_FILTER_GOOD:
469 case PIXMAN_FILTER_BEST:
470 case PIXMAN_FILTER_BILINEAR:
471 x_off = - pixman_fixed_1 / 2;
472 y_off = - pixman_fixed_1 / 2;
473 width = pixman_fixed_1;
474 height = pixman_fixed_1;
477 case PIXMAN_FILTER_FAST:
478 case PIXMAN_FILTER_NEAREST:
479 x_off = - pixman_fixed_e;
480 y_off = - pixman_fixed_e;
497 if (!compute_transformed_extents (transform, extents, &transformed))
500 /* Expand the source area by a tiny bit so account of different rounding that
501 * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
502 * 0.5 so this won't cause the area computed to be overly pessimistic.
504 transformed.x1 -= 8 * pixman_fixed_e;
505 transformed.y1 -= 8 * pixman_fixed_e;
506 transformed.x2 += 8 * pixman_fixed_e;
507 transformed.y2 += 8 * pixman_fixed_e;
509 if (image->common.type == BITS)
511 if (pixman_fixed_to_int (transformed.x1) >= 0 &&
512 pixman_fixed_to_int (transformed.y1) >= 0 &&
513 pixman_fixed_to_int (transformed.x2) < image->bits.width &&
514 pixman_fixed_to_int (transformed.y2) < image->bits.height)
516 *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
519 if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0 &&
520 pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0 &&
521 pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width &&
522 pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height)
524 *flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR;
528 /* Check we don't overflow when the destination extents are expanded by one.
529 * This ensures that compositing functions can simply walk the source space
530 * using 16.16 variables without worrying about overflow.
532 exp_extents = *extents;
538 if (!compute_transformed_extents (transform, &exp_extents, &transformed))
541 if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e) ||
542 !IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e) ||
543 !IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width) ||
544 !IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height))
553 * Work around GCC bug causing crashes in Mozilla with SSE2
555 * When using -msse, gcc generates movdqa instructions assuming that
556 * the stack is 16 byte aligned. Unfortunately some applications, such
557 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
558 * causes the movdqa instructions to fail.
560 * The __force_align_arg_pointer__ makes gcc generate a prologue that
561 * realigns the stack pointer to 16 bytes.
563 * On x86-64 this is not necessary because the standard ABI already
564 * calls for a 16 byte aligned stack.
566 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
568 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
569 __attribute__((__force_align_arg_pointer__))
572 pixman_image_composite32 (pixman_op_t op,
573 pixman_image_t * src,
574 pixman_image_t * mask,
575 pixman_image_t * dest,
585 pixman_format_code_t src_format, mask_format, dest_format;
586 uint32_t src_flags, mask_flags, dest_flags;
587 pixman_region32_t region;
588 pixman_box32_t extents;
589 pixman_implementation_t *imp;
590 pixman_composite_func_t func;
592 _pixman_image_validate (src);
594 _pixman_image_validate (mask);
595 _pixman_image_validate (dest);
597 src_format = src->common.extended_format_code;
598 src_flags = src->common.flags;
602 mask_format = mask->common.extended_format_code;
603 mask_flags = mask->common.flags;
607 mask_format = PIXMAN_null;
608 mask_flags = FAST_PATH_IS_OPAQUE;
611 dest_format = dest->common.extended_format_code;
612 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 (src_x == mask_x && src_y == mask_y))
620 if (src_format == PIXMAN_x8b8g8r8)
621 src_format = mask_format = PIXMAN_pixbuf;
622 else if (src_format == PIXMAN_x8r8g8b8)
623 src_format = mask_format = PIXMAN_rpixbuf;
626 pixman_region32_init (®ion);
628 if (!pixman_compute_composite_region32 (
629 ®ion, src, mask, dest,
630 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
635 extents = *pixman_region32_extents (®ion);
637 extents.x1 -= dest_x - src_x;
638 extents.y1 -= dest_y - src_y;
639 extents.x2 -= dest_x - src_x;
640 extents.y2 -= dest_y - src_y;
642 if (!analyze_extent (src, &extents, &src_flags))
645 extents.x1 -= src_x - mask_x;
646 extents.y1 -= src_y - mask_y;
647 extents.x2 -= src_x - mask_x;
648 extents.y2 -= src_y - mask_y;
650 if (!analyze_extent (mask, &extents, &mask_flags))
653 /* If the clip is within the source samples, and the samples are
654 * opaque, then the source is effectively opaque.
656 #define NEAREST_OPAQUE (FAST_PATH_SAMPLES_OPAQUE | \
657 FAST_PATH_NEAREST_FILTER | \
658 FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
659 #define BILINEAR_OPAQUE (FAST_PATH_SAMPLES_OPAQUE | \
660 FAST_PATH_BILINEAR_FILTER | \
661 FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR)
663 if ((src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
664 (src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
666 src_flags |= FAST_PATH_IS_OPAQUE;
669 if ((mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
670 (mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
672 mask_flags |= FAST_PATH_IS_OPAQUE;
676 * Check if we can replace our operator by a simpler one
677 * if the src or dest are opaque. The output operator should be
678 * mathematically equivalent to the source.
680 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
682 if (_pixman_lookup_composite_function (
683 get_implementation (), op,
684 src_format, src_flags, mask_format, mask_flags, dest_format, dest_flags,
687 pixman_composite_info_t info;
688 const pixman_box32_t *pbox;
692 info.src_image = src;
693 info.mask_image = mask;
694 info.dest_image = dest;
695 info.src_flags = src_flags;
696 info.mask_flags = mask_flags;
697 info.dest_flags = dest_flags;
699 pbox = pixman_region32_rectangles (®ion, &n);
703 info.src_x = pbox->x1 + src_x - dest_x;
704 info.src_y = pbox->y1 + src_y - dest_y;
705 info.mask_x = pbox->x1 + mask_x - dest_x;
706 info.mask_y = pbox->y1 + mask_y - dest_y;
707 info.dest_x = pbox->x1;
708 info.dest_y = pbox->y1;
709 info.width = pbox->x2 - pbox->x1;
710 info.height = pbox->y2 - pbox->y1;
719 pixman_region32_fini (®ion);
723 pixman_image_composite (pixman_op_t op,
724 pixman_image_t * src,
725 pixman_image_t * mask,
726 pixman_image_t * dest,
736 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
737 mask_x, mask_y, dest_x, dest_y, width, height);
740 PIXMAN_EXPORT pixman_bool_t
741 pixman_blt (uint32_t *src_bits,
754 return _pixman_implementation_blt (get_implementation(),
755 src_bits, dst_bits, src_stride, dst_stride,
762 PIXMAN_EXPORT pixman_bool_t
763 pixman_fill (uint32_t *bits,
772 return _pixman_implementation_fill (
773 get_implementation(), bits, stride, bpp, x, y, width, height, xor);
777 color_to_uint32 (const pixman_color_t *color)
780 (color->alpha >> 8 << 24) |
781 (color->red >> 8 << 16) |
782 (color->green & 0xff00) |
787 color_to_pixel (pixman_color_t * color,
789 pixman_format_code_t format)
791 uint32_t c = color_to_uint32 (color);
793 if (!(format == PIXMAN_a8r8g8b8 ||
794 format == PIXMAN_x8r8g8b8 ||
795 format == PIXMAN_a8b8g8r8 ||
796 format == PIXMAN_x8b8g8r8 ||
797 format == PIXMAN_b8g8r8a8 ||
798 format == PIXMAN_b8g8r8x8 ||
799 format == PIXMAN_r8g8b8a8 ||
800 format == PIXMAN_r8g8b8x8 ||
801 format == PIXMAN_r5g6b5 ||
802 format == PIXMAN_b5g6r5 ||
803 format == PIXMAN_a8 ||
804 format == PIXMAN_a1))
809 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
811 c = ((c & 0xff000000) >> 0) |
812 ((c & 0x00ff0000) >> 16) |
813 ((c & 0x0000ff00) >> 0) |
814 ((c & 0x000000ff) << 16);
816 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
818 c = ((c & 0xff000000) >> 24) |
819 ((c & 0x00ff0000) >> 8) |
820 ((c & 0x0000ff00) << 8) |
821 ((c & 0x000000ff) << 24);
823 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA)
824 c = ((c & 0xff000000) >> 24) | (c << 8);
826 if (format == PIXMAN_a1)
828 else if (format == PIXMAN_a8)
830 else if (format == PIXMAN_r5g6b5 ||
831 format == PIXMAN_b5g6r5)
832 c = CONVERT_8888_TO_0565 (c);
835 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
836 printf ("pixel: %x\n", c);
843 PIXMAN_EXPORT pixman_bool_t
844 pixman_image_fill_rectangles (pixman_op_t op,
845 pixman_image_t * dest,
846 pixman_color_t * color,
848 const pixman_rectangle16_t *rects)
850 pixman_box32_t stack_boxes[6];
851 pixman_box32_t *boxes;
852 pixman_bool_t result;
857 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
866 for (i = 0; i < n_rects; ++i)
868 boxes[i].x1 = rects[i].x;
869 boxes[i].y1 = rects[i].y;
870 boxes[i].x2 = boxes[i].x1 + rects[i].width;
871 boxes[i].y2 = boxes[i].y1 + rects[i].height;
874 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
876 if (boxes != stack_boxes)
882 PIXMAN_EXPORT pixman_bool_t
883 pixman_image_fill_boxes (pixman_op_t op,
884 pixman_image_t * dest,
885 pixman_color_t * color,
887 const pixman_box32_t *boxes)
889 pixman_image_t *solid;
893 _pixman_image_validate (dest);
895 if (color->alpha == 0xffff)
897 if (op == PIXMAN_OP_OVER)
901 if (op == PIXMAN_OP_CLEAR)
913 if (op == PIXMAN_OP_SRC)
917 if (color_to_pixel (color, &pixel, dest->bits.format))
919 pixman_region32_t fill_region;
921 pixman_box32_t *rects;
923 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
926 if (dest->common.have_clip_region)
928 if (!pixman_region32_intersect (&fill_region,
930 &dest->common.clip_region))
934 rects = pixman_region32_rectangles (&fill_region, &n_rects);
935 for (j = 0; j < n_rects; ++j)
937 const pixman_box32_t *rect = &(rects[j]);
938 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
939 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
943 pixman_region32_fini (&fill_region);
948 solid = pixman_image_create_solid_fill (color);
952 for (i = 0; i < n_boxes; ++i)
954 const pixman_box32_t *box = &(boxes[i]);
956 pixman_image_composite32 (op, solid, NULL, dest,
959 box->x2 - box->x1, box->y2 - box->y1);
962 pixman_image_unref (solid);
970 * Returns the version of the pixman library encoded in a single
971 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
972 * later versions compare greater than earlier versions.
974 * A run-time comparison to check that pixman's version is greater than
975 * or equal to version X.Y.Z could be performed as follows:
977 * <informalexample><programlisting>
978 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
979 * </programlisting></informalexample>
981 * See also pixman_version_string() as well as the compile-time
982 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
984 * Return value: the encoded version.
987 pixman_version (void)
989 return PIXMAN_VERSION;
993 * pixman_version_string:
995 * Returns the version of the pixman library as a human-readable string
996 * of the form "X.Y.Z".
998 * See also pixman_version() as well as the compile-time equivalents
999 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1001 * Return value: a string containing the version.
1003 PIXMAN_EXPORT const char*
1004 pixman_version_string (void)
1006 return PIXMAN_VERSION_STRING;
1010 * pixman_format_supported_source:
1011 * @format: A pixman_format_code_t format
1013 * Return value: whether the provided format code is a supported
1014 * format for a pixman surface used as a source in
1017 * Currently, all pixman_format_code_t values are supported.
1019 PIXMAN_EXPORT pixman_bool_t
1020 pixman_format_supported_source (pixman_format_code_t format)
1024 /* 32 bpp formats */
1025 case PIXMAN_a2b10g10r10:
1026 case PIXMAN_x2b10g10r10:
1027 case PIXMAN_a2r10g10b10:
1028 case PIXMAN_x2r10g10b10:
1029 case PIXMAN_a8r8g8b8:
1030 case PIXMAN_x8r8g8b8:
1031 case PIXMAN_a8b8g8r8:
1032 case PIXMAN_x8b8g8r8:
1033 case PIXMAN_b8g8r8a8:
1034 case PIXMAN_b8g8r8x8:
1035 case PIXMAN_r8g8b8a8:
1036 case PIXMAN_r8g8b8x8:
1041 case PIXMAN_x14r6g6b6:
1042 /* 16 bpp formats */
1043 case PIXMAN_a1r5g5b5:
1044 case PIXMAN_x1r5g5b5:
1045 case PIXMAN_a1b5g5r5:
1046 case PIXMAN_x1b5g5r5:
1047 case PIXMAN_a4r4g4b4:
1048 case PIXMAN_x4r4g4b4:
1049 case PIXMAN_a4b4g4r4:
1050 case PIXMAN_x4b4g4r4:
1055 case PIXMAN_a2r2g2b2:
1056 case PIXMAN_a2b2g2r2:
1060 /* Collides with PIXMAN_c8
1063 /* Collides with PIXMAN_g8
1070 case PIXMAN_a1r1g1b1:
1071 case PIXMAN_a1b1g1r1:
1088 * pixman_format_supported_destination:
1089 * @format: A pixman_format_code_t format
1091 * Return value: whether the provided format code is a supported
1092 * format for a pixman surface used as a destination in
1095 * Currently, all pixman_format_code_t values are supported
1096 * except for the YUV formats.
1098 PIXMAN_EXPORT pixman_bool_t
1099 pixman_format_supported_destination (pixman_format_code_t format)
1101 /* YUV formats cannot be written to at the moment */
1102 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1105 return pixman_format_supported_source (format);
1108 PIXMAN_EXPORT pixman_bool_t
1109 pixman_compute_composite_region (pixman_region16_t * region,
1110 pixman_image_t * src_image,
1111 pixman_image_t * mask_image,
1112 pixman_image_t * dest_image,
1122 pixman_region32_t r32;
1123 pixman_bool_t retval;
1125 pixman_region32_init (&r32);
1127 retval = pixman_compute_composite_region32 (
1128 &r32, src_image, mask_image, dest_image,
1129 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1134 if (!pixman_region16_copy_from_region32 (region, &r32))
1138 pixman_region32_fini (&r32);