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 *imp;
35 #define PACK(a, b, c, d) \
36 (((uint8_t)PIXMAN_OP_ ## a << 0) | \
37 ((uint8_t)PIXMAN_OP_ ## b << 8) | \
38 ((uint8_t)PIXMAN_OP_ ## c << 16) | \
39 ((uint8_t)PIXMAN_OP_ ## d << 24))
41 static const uint32_t operator_table[] =
43 /* Neither Opaque Src Opaque Dst Opaque Both Opaque */
44 PACK (CLEAR, CLEAR, CLEAR, CLEAR),
45 PACK (SRC, SRC, SRC, SRC),
46 PACK (DST, DST, DST, DST),
47 PACK (OVER, SRC, OVER, SRC),
48 PACK (OVER_REVERSE, OVER_REVERSE, DST, DST),
49 PACK (IN, IN, SRC, SRC),
50 PACK (IN_REVERSE, DST, IN_REVERSE, DST),
51 PACK (OUT, OUT, CLEAR, CLEAR),
52 PACK (OUT_REVERSE, CLEAR, OUT_REVERSE, CLEAR),
53 PACK (ATOP, IN, OVER, SRC),
54 PACK (ATOP_REVERSE, OVER_REVERSE, IN_REVERSE, DST),
55 PACK (XOR, OUT, OUT_REVERSE, CLEAR),
56 PACK (ADD, ADD, ADD, ADD),
57 PACK (SATURATE, OVER_REVERSE, DST, DST),
62 PACK (DISJOINT_CLEAR, DISJOINT_CLEAR, DISJOINT_CLEAR, DISJOINT_CLEAR),
63 PACK (DISJOINT_SRC, DISJOINT_SRC, DISJOINT_SRC, DISJOINT_SRC),
64 PACK (DISJOINT_DST, DISJOINT_DST, DISJOINT_DST, DISJOINT_DST),
65 PACK (DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER),
66 PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
67 PACK (DISJOINT_IN, DISJOINT_IN, DISJOINT_IN, DISJOINT_IN),
68 PACK (DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE),
69 PACK (DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT),
70 PACK (DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE),
71 PACK (DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP),
72 PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
73 PACK (DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR),
80 PACK (CONJOINT_CLEAR, CONJOINT_CLEAR, CONJOINT_CLEAR, CONJOINT_CLEAR),
81 PACK (CONJOINT_SRC, CONJOINT_SRC, CONJOINT_SRC, CONJOINT_SRC),
82 PACK (CONJOINT_DST, CONJOINT_DST, CONJOINT_DST, CONJOINT_DST),
83 PACK (CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER),
84 PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
85 PACK (CONJOINT_IN, CONJOINT_IN, CONJOINT_IN, CONJOINT_IN),
86 PACK (CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE),
87 PACK (CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT),
88 PACK (CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE),
89 PACK (CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP),
90 PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
91 PACK (CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR),
98 PACK (MULTIPLY, MULTIPLY, MULTIPLY, MULTIPLY),
99 PACK (SCREEN, SCREEN, SCREEN, SCREEN),
100 PACK (OVERLAY, OVERLAY, OVERLAY, OVERLAY),
101 PACK (DARKEN, DARKEN, DARKEN, DARKEN),
102 PACK (LIGHTEN, LIGHTEN, LIGHTEN, LIGHTEN),
103 PACK (COLOR_DODGE, COLOR_DODGE, COLOR_DODGE, COLOR_DODGE),
104 PACK (COLOR_BURN, COLOR_BURN, COLOR_BURN, COLOR_BURN),
105 PACK (HARD_LIGHT, HARD_LIGHT, HARD_LIGHT, HARD_LIGHT),
106 PACK (SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT),
107 PACK (DIFFERENCE, DIFFERENCE, DIFFERENCE, DIFFERENCE),
108 PACK (EXCLUSION, EXCLUSION, EXCLUSION, EXCLUSION),
109 PACK (HSL_HUE, HSL_HUE, HSL_HUE, HSL_HUE),
110 PACK (HSL_SATURATION, HSL_SATURATION, HSL_SATURATION, HSL_SATURATION),
111 PACK (HSL_COLOR, HSL_COLOR, HSL_COLOR, HSL_COLOR),
112 PACK (HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY),
118 * Optimize the current operator based on opacity of source or destination
119 * The output operator should be mathematically equivalent to the source.
122 optimize_operator (pixman_op_t op,
127 pixman_bool_t is_source_opaque, is_dest_opaque;
130 is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE) != 0;
131 is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE) != 0;
133 shift = 8 * ((is_dest_opaque << 1) | is_source_opaque);
135 return (operator_table[op] >> shift) & 0xff;
139 apply_workaround (pixman_image_t *image,
142 uint32_t ** save_bits,
146 if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
148 /* Some X servers generate images that point to the
149 * wrong place in memory, but then set the clip region
150 * to point to the right place. Because of an old bug
151 * in pixman, this would actually work.
153 * Here we try and undo the damage
155 int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
156 pixman_box32_t *extents;
160 extents = pixman_region32_extents (&(image->common.clip_region));
164 *save_bits = image->bits.bits;
168 pixman_region32_translate (&(image->common.clip_region), -dx, -dy);
170 t = (uint8_t *)image->bits.bits;
171 t += dy * image->bits.rowstride * 4 + dx * bpp;
172 image->bits.bits = (uint32_t *)t;
180 unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy)
182 if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
184 image->bits.bits = bits;
185 pixman_region32_translate (&image->common.clip_region, dx, dy);
190 * Computing composite region
192 static inline pixman_bool_t
193 clip_general_image (pixman_region32_t * region,
194 pixman_region32_t * clip,
198 if (pixman_region32_n_rects (region) == 1 &&
199 pixman_region32_n_rects (clip) == 1)
201 pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
202 pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
205 if (rbox->x1 < (v = cbox->x1 + dx))
207 if (rbox->x2 > (v = cbox->x2 + dx))
209 if (rbox->y1 < (v = cbox->y1 + dy))
211 if (rbox->y2 > (v = cbox->y2 + dy))
213 if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
215 pixman_region32_init (region);
219 else if (!pixman_region32_not_empty (clip))
226 pixman_region32_translate (region, -dx, -dy);
228 if (!pixman_region32_intersect (region, region, clip))
232 pixman_region32_translate (region, dx, dy);
235 return pixman_region32_not_empty (region);
238 static inline pixman_bool_t
239 clip_source_image (pixman_region32_t * region,
240 pixman_image_t * image,
244 /* Source clips are ignored, unless they are explicitly turned on
245 * and the clip in question was set by an X client. (Because if
246 * the clip was not set by a client, then it is a hierarchy
247 * clip and those should always be ignored for sources).
249 if (!image->common.clip_sources || !image->common.client_clip)
252 return clip_general_image (region,
253 &image->common.clip_region,
258 * returns FALSE if the final region is empty. Indistinguishable from
259 * an allocation failure, but rendering ignores those anyways.
262 pixman_compute_composite_region32 (pixman_region32_t * region,
263 pixman_image_t * src_image,
264 pixman_image_t * mask_image,
265 pixman_image_t * dst_image,
275 region->extents.x1 = dest_x;
276 region->extents.x2 = dest_x + width;
277 region->extents.y1 = dest_y;
278 region->extents.y2 = dest_y + height;
280 region->extents.x1 = MAX (region->extents.x1, 0);
281 region->extents.y1 = MAX (region->extents.y1, 0);
282 region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
283 region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
287 /* Check for empty operation */
288 if (region->extents.x1 >= region->extents.x2 ||
289 region->extents.y1 >= region->extents.y2)
291 pixman_region32_init (region);
295 if (dst_image->common.have_clip_region)
297 if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
299 pixman_region32_fini (region);
304 if (dst_image->common.alpha_map && dst_image->common.alpha_map->common.have_clip_region)
306 if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
307 -dst_image->common.alpha_origin_x,
308 -dst_image->common.alpha_origin_y))
310 pixman_region32_fini (region);
315 /* clip against src */
316 if (src_image->common.have_clip_region)
318 if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
320 pixman_region32_fini (region);
324 if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
326 if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
327 dest_x - (src_x - src_image->common.alpha_origin_x),
328 dest_y - (src_y - src_image->common.alpha_origin_y)))
330 pixman_region32_fini (region);
334 /* clip against mask */
335 if (mask_image && mask_image->common.have_clip_region)
337 if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
339 pixman_region32_fini (region);
342 if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
344 if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
345 dest_x - (mask_x - mask_image->common.alpha_origin_x),
346 dest_y - (mask_y - mask_image->common.alpha_origin_y)))
348 pixman_region32_fini (region);
358 walk_region_internal (pixman_implementation_t *imp,
360 pixman_image_t * src_image,
361 pixman_image_t * mask_image,
362 pixman_image_t * dst_image,
371 pixman_bool_t src_repeat,
372 pixman_bool_t mask_repeat,
373 pixman_region32_t * region,
374 pixman_composite_func_t composite_rect)
376 int w, h, w_this, h_this;
377 int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
378 int src_dy = src_y - dest_y;
379 int src_dx = src_x - dest_x;
380 int mask_dy = mask_y - dest_y;
381 int mask_dx = mask_x - dest_x;
382 const pixman_box32_t *pbox;
385 pbox = pixman_region32_rectangles (region, &n);
387 /* Fast path for non-repeating sources */
388 if (!src_repeat && !mask_repeat)
392 (*composite_rect) (imp, op,
393 src_image, mask_image, dst_image,
401 pbox->y2 - pbox->y1);
411 h = pbox->y2 - pbox->y1;
412 y_src = pbox->y1 + src_dy;
413 y_msk = pbox->y1 + mask_dy;
419 w = pbox->x2 - pbox->x1;
420 x_src = pbox->x1 + src_dx;
421 x_msk = pbox->x1 + mask_dx;
426 y_msk = MOD (y_msk, mask_image->bits.height);
427 if (h_this > mask_image->bits.height - y_msk)
428 h_this = mask_image->bits.height - y_msk;
433 y_src = MOD (y_src, src_image->bits.height);
434 if (h_this > src_image->bits.height - y_src)
435 h_this = src_image->bits.height - y_src;
444 x_msk = MOD (x_msk, mask_image->bits.width);
445 if (w_this > mask_image->bits.width - x_msk)
446 w_this = mask_image->bits.width - x_msk;
451 x_src = MOD (x_src, src_image->bits.width);
452 if (w_this > src_image->bits.width - x_src)
453 w_this = src_image->bits.width - x_src;
456 (*composite_rect) (imp, op,
457 src_image, mask_image, dst_image,
458 x_src, y_src, x_msk, y_msk, x_dst, y_dst,
477 static force_inline pixman_bool_t
478 image_covers (pixman_image_t *image,
479 pixman_box32_t *extents,
483 if (image->common.type == BITS &&
484 image->common.repeat == PIXMAN_REPEAT_NONE)
486 if (x > extents->x1 || y > extents->y1 ||
487 x + image->bits.width < extents->x2 ||
488 y + image->bits.height < extents->y2)
498 do_composite (pixman_implementation_t *imp,
501 pixman_image_t *mask,
502 pixman_image_t *dest,
512 #define N_CACHED_FAST_PATHS 8
513 static THREAD_LOCAL pixman_fast_path_t tls_cache[N_CACHED_FAST_PATHS];
514 pixman_format_code_t src_format, mask_format, dest_format;
515 uint32_t src_flags, mask_flags, dest_flags;
516 pixman_region32_t region;
517 pixman_box32_t *extents;
521 int mask_dx, mask_dy;
523 int dest_dx, dest_dy;
524 pixman_bool_t need_workaround;
525 pixman_fast_path_t *cache;
526 const pixman_fast_path_t *info;
529 src_format = src->common.extended_format_code;
530 src_flags = src->common.flags;
534 mask_format = mask->common.extended_format_code;
535 mask_flags = mask->common.flags;
539 mask_format = PIXMAN_null;
540 mask_flags = FAST_PATH_IS_OPAQUE;
543 dest_format = dest->common.extended_format_code;
544 dest_flags = dest->common.flags;
546 /* Check for pixbufs */
547 if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
548 (src->type == BITS && src->bits.bits == mask->bits.bits) &&
549 (src->common.repeat == mask->common.repeat) &&
550 (src_x == mask_x && src_y == mask_y))
552 if (src_format == PIXMAN_x8b8g8r8)
553 src_format = mask_format = PIXMAN_pixbuf;
554 else if (src_format == PIXMAN_x8r8g8b8)
555 src_format = mask_format = PIXMAN_rpixbuf;
558 /* Check for workaround */
559 need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
563 apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
564 apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
565 apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
568 pixman_region32_init (®ion);
570 if (!pixman_compute_composite_region32 (
571 ®ion, src, mask, dest,
572 src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
577 extents = pixman_region32_extents (®ion);
579 if (image_covers (src, extents, dest_x - src_x, dest_y - src_y))
580 src_flags |= FAST_PATH_COVERS_CLIP;
582 if (mask && image_covers (mask, extents, dest_x - mask_x, dest_y - mask_y))
583 mask_flags |= FAST_PATH_COVERS_CLIP;
586 * Check if we can replace our operator by a simpler one
587 * if the src or dest are opaque. The output operator should be
588 * mathematically equivalent to the source.
590 op = optimize_operator (op, src_flags, mask_flags, dest_flags);
591 if (op == PIXMAN_OP_DST ||
592 op == PIXMAN_OP_CONJOINT_DST ||
593 op == PIXMAN_OP_DISJOINT_DST)
600 for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
604 /* Note that we check for equality here, not whether
605 * the cached fast path matches. This is to prevent
606 * us from selecting an overly general fast path
607 * when a more specific one would work.
609 if (info->op == op &&
610 info->src_format == src_format &&
611 info->mask_format == mask_format &&
612 info->dest_format == dest_format &&
613 info->src_flags == src_flags &&
614 info->mask_flags == mask_flags &&
615 info->dest_flags == dest_flags &&
624 info = imp->fast_paths;
626 while (info->op != PIXMAN_OP_NONE)
628 if ((info->op == op || info->op == PIXMAN_OP_any) &&
630 ((info->src_format == src_format) ||
631 (info->src_format == PIXMAN_any)) &&
632 ((info->mask_format == mask_format) ||
633 (info->mask_format == PIXMAN_any)) &&
634 ((info->dest_format == dest_format) ||
635 (info->dest_format == PIXMAN_any)) &&
637 (info->src_flags & src_flags) == info->src_flags &&
638 (info->mask_flags & mask_flags) == info->mask_flags &&
639 (info->dest_flags & dest_flags) == info->dest_flags)
641 /* Set i to the last spot in the cache so that the
642 * move-to-front code below will work
644 i = N_CACHED_FAST_PATHS - 1;
655 /* We didn't find a compositing routine. This should not happen, but if
656 * it somehow does, just exit rather than crash.
661 walk_region_internal (imp, op,
663 src_x, src_y, mask_x, mask_y,
666 (src_flags & FAST_PATH_SIMPLE_REPEAT),
667 (mask_flags & FAST_PATH_SIMPLE_REPEAT),
668 ®ion, info->func);
672 /* Make a copy of info->func, because info->func may change when
673 * we update the cache.
675 pixman_composite_func_t func = info->func;
678 cache[i + 1] = cache[i];
681 cache[0].src_format = src_format;
682 cache[0].src_flags = src_flags;
683 cache[0].mask_format = mask_format;
684 cache[0].mask_flags = mask_flags;
685 cache[0].dest_format = dest_format;
686 cache[0].dest_flags = dest_flags;
687 cache[0].func = func;
693 unapply_workaround (src, src_bits, src_dx, src_dy);
694 unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
695 unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
698 pixman_region32_fini (®ion);
702 pixman_image_composite (pixman_op_t op,
703 pixman_image_t * src,
704 pixman_image_t * mask,
705 pixman_image_t * dest,
715 pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
716 mask_x, mask_y, dest_x, dest_y, width, height);
720 * Work around GCC bug causing crashes in Mozilla with SSE2
722 * When using -msse, gcc generates movdqa instructions assuming that
723 * the stack is 16 byte aligned. Unfortunately some applications, such
724 * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
725 * causes the movdqa instructions to fail.
727 * The __force_align_arg_pointer__ makes gcc generate a prologue that
728 * realigns the stack pointer to 16 bytes.
730 * On x86-64 this is not necessary because the standard ABI already
731 * calls for a 16 byte aligned stack.
733 * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
735 #if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
736 __attribute__((__force_align_arg_pointer__))
739 pixman_image_composite32 (pixman_op_t op,
740 pixman_image_t * src,
741 pixman_image_t * mask,
742 pixman_image_t * dest,
752 _pixman_image_validate (src);
754 _pixman_image_validate (mask);
755 _pixman_image_validate (dest);
758 imp = _pixman_choose_implementation ();
760 do_composite (imp, op,
768 PIXMAN_EXPORT pixman_bool_t
769 pixman_blt (uint32_t *src_bits,
783 imp = _pixman_choose_implementation ();
785 return _pixman_implementation_blt (imp, src_bits, dst_bits, src_stride, dst_stride,
792 PIXMAN_EXPORT pixman_bool_t
793 pixman_fill (uint32_t *bits,
803 imp = _pixman_choose_implementation ();
805 return _pixman_implementation_fill (imp, bits, stride, bpp, x, y, width, height, xor);
809 color_to_uint32 (const pixman_color_t *color)
812 (color->alpha >> 8 << 24) |
813 (color->red >> 8 << 16) |
814 (color->green & 0xff00) |
819 color_to_pixel (pixman_color_t * color,
821 pixman_format_code_t format)
823 uint32_t c = color_to_uint32 (color);
825 if (!(format == PIXMAN_a8r8g8b8 ||
826 format == PIXMAN_x8r8g8b8 ||
827 format == PIXMAN_a8b8g8r8 ||
828 format == PIXMAN_x8b8g8r8 ||
829 format == PIXMAN_b8g8r8a8 ||
830 format == PIXMAN_b8g8r8x8 ||
831 format == PIXMAN_r5g6b5 ||
832 format == PIXMAN_b5g6r5 ||
833 format == PIXMAN_a8))
838 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
840 c = ((c & 0xff000000) >> 0) |
841 ((c & 0x00ff0000) >> 16) |
842 ((c & 0x0000ff00) >> 0) |
843 ((c & 0x000000ff) << 16);
845 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
847 c = ((c & 0xff000000) >> 24) |
848 ((c & 0x00ff0000) >> 8) |
849 ((c & 0x0000ff00) << 8) |
850 ((c & 0x000000ff) << 24);
853 if (format == PIXMAN_a8)
855 else if (format == PIXMAN_r5g6b5 ||
856 format == PIXMAN_b5g6r5)
857 c = CONVERT_8888_TO_0565 (c);
860 printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
861 printf ("pixel: %x\n", c);
868 PIXMAN_EXPORT pixman_bool_t
869 pixman_image_fill_rectangles (pixman_op_t op,
870 pixman_image_t * dest,
871 pixman_color_t * color,
873 const pixman_rectangle16_t *rects)
875 pixman_box32_t stack_boxes[6];
876 pixman_box32_t *boxes;
877 pixman_bool_t result;
882 boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
891 for (i = 0; i < n_rects; ++i)
893 boxes[i].x1 = rects[i].x;
894 boxes[i].y1 = rects[i].y;
895 boxes[i].x2 = boxes[i].x1 + rects[i].width;
896 boxes[i].y2 = boxes[i].y1 + rects[i].height;
899 result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
901 if (boxes != stack_boxes)
907 PIXMAN_EXPORT pixman_bool_t
908 pixman_image_fill_boxes (pixman_op_t op,
909 pixman_image_t * dest,
910 pixman_color_t * color,
912 const pixman_box32_t *boxes)
914 pixman_image_t *solid;
918 _pixman_image_validate (dest);
920 if (color->alpha == 0xffff)
922 if (op == PIXMAN_OP_OVER)
926 if (op == PIXMAN_OP_CLEAR)
938 if (op == PIXMAN_OP_SRC)
942 if (color_to_pixel (color, &pixel, dest->bits.format))
944 pixman_region32_t fill_region;
946 pixman_box32_t *rects;
948 if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
951 if (dest->common.have_clip_region)
953 if (!pixman_region32_intersect (&fill_region,
955 &dest->common.clip_region))
959 rects = pixman_region32_rectangles (&fill_region, &n_rects);
960 for (j = 0; j < n_rects; ++j)
962 const pixman_box32_t *rect = &(rects[j]);
963 pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
964 rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
968 pixman_region32_fini (&fill_region);
973 solid = pixman_image_create_solid_fill (color);
977 for (i = 0; i < n_boxes; ++i)
979 const pixman_box32_t *box = &(boxes[i]);
981 pixman_image_composite32 (op, solid, NULL, dest,
984 box->x2 - box->x1, box->y2 - box->y1);
987 pixman_image_unref (solid);
995 * Returns the version of the pixman library encoded in a single
996 * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
997 * later versions compare greater than earlier versions.
999 * A run-time comparison to check that pixman's version is greater than
1000 * or equal to version X.Y.Z could be performed as follows:
1002 * <informalexample><programlisting>
1003 * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
1004 * </programlisting></informalexample>
1006 * See also pixman_version_string() as well as the compile-time
1007 * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
1009 * Return value: the encoded version.
1012 pixman_version (void)
1014 return PIXMAN_VERSION;
1018 * pixman_version_string:
1020 * Returns the version of the pixman library as a human-readable string
1021 * of the form "X.Y.Z".
1023 * See also pixman_version() as well as the compile-time equivalents
1024 * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
1026 * Return value: a string containing the version.
1028 PIXMAN_EXPORT const char*
1029 pixman_version_string (void)
1031 return PIXMAN_VERSION_STRING;
1035 * pixman_format_supported_source:
1036 * @format: A pixman_format_code_t format
1038 * Return value: whether the provided format code is a supported
1039 * format for a pixman surface used as a source in
1042 * Currently, all pixman_format_code_t values are supported.
1044 PIXMAN_EXPORT pixman_bool_t
1045 pixman_format_supported_source (pixman_format_code_t format)
1049 /* 32 bpp formats */
1050 case PIXMAN_a2b10g10r10:
1051 case PIXMAN_x2b10g10r10:
1052 case PIXMAN_a2r10g10b10:
1053 case PIXMAN_x2r10g10b10:
1054 case PIXMAN_a8r8g8b8:
1055 case PIXMAN_x8r8g8b8:
1056 case PIXMAN_a8b8g8r8:
1057 case PIXMAN_x8b8g8r8:
1058 case PIXMAN_b8g8r8a8:
1059 case PIXMAN_b8g8r8x8:
1064 /* 16 bpp formats */
1065 case PIXMAN_a1r5g5b5:
1066 case PIXMAN_x1r5g5b5:
1067 case PIXMAN_a1b5g5r5:
1068 case PIXMAN_x1b5g5r5:
1069 case PIXMAN_a4r4g4b4:
1070 case PIXMAN_x4r4g4b4:
1071 case PIXMAN_a4b4g4r4:
1072 case PIXMAN_x4b4g4r4:
1077 case PIXMAN_a2r2g2b2:
1078 case PIXMAN_a2b2g2r2:
1082 /* Collides with PIXMAN_c8
1085 /* Collides with PIXMAN_g8
1092 case PIXMAN_a1r1g1b1:
1093 case PIXMAN_a1b1g1r1:
1110 * pixman_format_supported_destination:
1111 * @format: A pixman_format_code_t format
1113 * Return value: whether the provided format code is a supported
1114 * format for a pixman surface used as a destination in
1117 * Currently, all pixman_format_code_t values are supported
1118 * except for the YUV formats.
1120 PIXMAN_EXPORT pixman_bool_t
1121 pixman_format_supported_destination (pixman_format_code_t format)
1123 /* YUV formats cannot be written to at the moment */
1124 if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
1127 return pixman_format_supported_source (format);
1130 PIXMAN_EXPORT pixman_bool_t
1131 pixman_compute_composite_region (pixman_region16_t * region,
1132 pixman_image_t * src_image,
1133 pixman_image_t * mask_image,
1134 pixman_image_t * dst_image,
1144 pixman_region32_t r32;
1145 pixman_bool_t retval;
1147 pixman_region32_init (&r32);
1149 retval = pixman_compute_composite_region32 (
1150 &r32, src_image, mask_image, dst_image,
1151 src_x, src_y, mask_x, mask_y, dest_x, dest_y,
1156 if (!pixman_region16_copy_from_region32 (region, &r32))
1160 pixman_region32_fini (&r32);