[cairo-commit] 2 commits - src/cairo-image-surface.c src/cairoint.h src/cairo-xlib-surface.c
Benjamin Otte
company at kemper.freedesktop.org
Thu Sep 24 15:16:53 PDT 2009
src/cairo-image-surface.c | 21 +++++++++----------
src/cairo-xlib-surface.c | 50 ++++++++++++++++++++++++++++++++++++++++------
src/cairoint.h | 2 -
3 files changed, 55 insertions(+), 18 deletions(-)
New commits:
commit caa9eed4646e78a62ffb49d9c4f48c0b351c7a7f
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Sep 24 23:42:05 2009 +0200
[xlib] Handle case in draw_image() where pixman format is not RGB
When an image cannot be expressed as masks, its data cannot be used in
an XImage. In that case, we use pixman to copy the image to the desired
format.
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 2b8d31a..45debd4 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -974,12 +974,11 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
XImage ximage;
cairo_format_masks_t image_masks;
int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;
+ pixman_image_t *pixman_image = NULL;
cairo_status_t status;
cairo_bool_t own_data;
GC gc;
- _pixman_format_to_masks (image->pixman_format, &image_masks);
-
ximage.width = image->width;
ximage.height = image->height;
ximage.format = ZPixmap;
@@ -993,10 +992,47 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
ximage.blue_mask = surface->b_mask;
ximage.xoffset = 0;
- if ((image_masks.alpha_mask == surface->a_mask || surface->a_mask == 0) &&
- (image_masks.red_mask == surface->r_mask || surface->r_mask == 0) &&
- (image_masks.green_mask == surface->g_mask || surface->g_mask == 0) &&
- (image_masks.blue_mask == surface->b_mask || surface->b_mask == 0))
+ if (!_pixman_format_to_masks (image->pixman_format, &image_masks))
+ {
+ pixman_format_code_t intermediate_format;
+ int ret;
+
+ image_masks.alpha_mask = surface->a_mask;
+ image_masks.red_mask = surface->r_mask;
+ image_masks.green_mask = surface->g_mask;
+ image_masks.blue_mask = surface->b_mask;
+ ret = _pixman_format_from_masks (&image_masks, &intermediate_format);
+ assert (ret);
+
+ pixman_image = pixman_image_create_bits (intermediate_format,
+ image->width,
+ image->height,
+ NULL,
+ 0);
+ if (pixman_image == NULL)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ pixman_image_composite (PIXMAN_OP_SRC,
+ image->pixman_image,
+ NULL,
+ pixman_image,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ image->width, image->height);
+
+ ximage.bits_per_pixel = image_masks.bpp;
+ ximage.data = (char *) pixman_image_get_data (pixman_image);
+ ximage.bytes_per_line = pixman_image_get_stride (pixman_image);
+ own_data = FALSE;
+
+ ret = XInitImage (&ximage);
+ assert (ret != 0);
+ }
+ else if ((image_masks.alpha_mask == surface->a_mask || surface->a_mask == 0) &&
+ (image_masks.red_mask == surface->r_mask || surface->r_mask == 0) &&
+ (image_masks.green_mask == surface->g_mask || surface->g_mask == 0) &&
+ (image_masks.blue_mask == surface->b_mask || surface->b_mask == 0))
{
int ret;
@@ -1126,6 +1162,8 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
BAIL:
if (own_data)
free (ximage.data);
+ if (pixman_image)
+ pixman_image_unref (pixman_image);
return CAIRO_STATUS_SUCCESS;
}
commit 9f5fe6711566ee34afe210f271f1c5a061efa745
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Sep 24 22:57:39 2009 +0200
[image] Return cairo_bool_t from _pixman_format_to_masks
Return FALSE when the pixman format does not support ARGB masks. In
particular, return FALSE for YUV formats.
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 0c5cc76..29ed119 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -231,11 +231,10 @@ _pixman_format_from_masks (cairo_format_masks_t *masks,
* expected. This avoid any problems from something bizarre like
* alpha in the least-significant bits, or insane channel order,
* or whatever. */
- _pixman_format_to_masks (format, &format_masks);
-
- if (masks->bpp != format_masks.bpp ||
- masks->red_mask != format_masks.red_mask ||
- masks->green_mask != format_masks.green_mask ||
+ if (!_pixman_format_to_masks (format, &format_masks) ||
+ masks->bpp != format_masks.bpp ||
+ masks->red_mask != format_masks.red_mask ||
+ masks->green_mask != format_masks.green_mask ||
masks->blue_mask != format_masks.blue_mask)
{
return FALSE;
@@ -248,7 +247,7 @@ _pixman_format_from_masks (cairo_format_masks_t *masks,
/* A mask consisting of N bits set to 1. */
#define MASK(N) ((1UL << (N))-1)
-void
+cairo_bool_t
_pixman_format_to_masks (pixman_format_code_t format,
cairo_format_masks_t *masks)
{
@@ -268,27 +267,27 @@ _pixman_format_to_masks (pixman_format_code_t format,
masks->red_mask = MASK (r) << (g + b);
masks->green_mask = MASK (g) << (b);
masks->blue_mask = MASK (b);
- return;
+ return TRUE;
case PIXMAN_TYPE_ABGR:
masks->alpha_mask = MASK (a) << (b + g + r);
masks->blue_mask = MASK (b) << (g + r);
masks->green_mask = MASK (g) << (r);
masks->red_mask = MASK (r);
- return;
+ return TRUE;
#ifdef PIXMAN_TYPE_BGRA
case PIXMAN_TYPE_BGRA:
masks->blue_mask = MASK (b) << (g + r + a);
masks->green_mask = MASK (g) << (r + a);
masks->red_mask = MASK (r) << (a);
masks->alpha_mask = MASK (a);
- return;
+ return TRUE;
#endif
case PIXMAN_TYPE_A:
masks->alpha_mask = MASK (a);
masks->red_mask = 0;
masks->green_mask = 0;
masks->blue_mask = 0;
- return;
+ return TRUE;
case PIXMAN_TYPE_OTHER:
case PIXMAN_TYPE_COLOR:
case PIXMAN_TYPE_GRAY:
@@ -299,7 +298,7 @@ _pixman_format_to_masks (pixman_format_code_t format,
masks->red_mask = 0;
masks->green_mask = 0;
masks->blue_mask = 0;
- return;
+ return FALSE;
}
}
diff --git a/src/cairoint.h b/src/cairoint.h
index 8b82454..ccf790a 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2230,7 +2230,7 @@ cairo_private cairo_bool_t
_pixman_format_from_masks (cairo_format_masks_t *masks,
pixman_format_code_t *format_ret);
-cairo_private void
+cairo_private cairo_bool_t
_pixman_format_to_masks (pixman_format_code_t pixman_format,
cairo_format_masks_t *masks);
More information about the cairo-commit
mailing list