[cairo-commit] 2 commits - src/cairo-image-surface.c src/cairoint.h src/cairo-type1-subset.c src/cairo-xlib-surface.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Oct 15 02:55:28 PDT 2008


 src/cairo-image-surface.c |   13 +++-----
 src/cairo-type1-subset.c  |    8 ++---
 src/cairo-xlib-surface.c  |   70 ++++++++++++++++++++++++++++++++++++++--------
 src/cairoint.h            |    2 -
 4 files changed, 70 insertions(+), 23 deletions(-)

New commits:
commit e17f02add019d9acf461a1ad1245ba5be00cf336
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 15 10:52:33 2008 +0100

    [type1] Protect against read macro
    
    POSIX allows for any of its functions to be implemented as a macro,
    inflicting damage upon innocent function pointers that happen to share
    the same name.
    
    face->stream->read() is one such example.
    
    As it's outside of our control (being a FT_Face) we cannot simply rename
    the data member, so we need to explicitly dereference it as a function
    pointer in order to disambiguate it for the compiler.

diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index a9005d3..ddcb660 100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -1214,10 +1214,10 @@ cairo_type1_font_subset_generate (void       *abstract_font,
 	goto fail;
     }
 
-    if (font->face->stream->read) {
-	ret = font->face->stream->read (font->face->stream, 0,
-					(unsigned char *) font->type1_data,
-					font->type1_length);
+    if (font->face->stream->read != NULL) {
+	ret = (* font->face->stream->read) (font->face->stream, 0,
+					    (unsigned char *) font->type1_data,
+					    font->type1_length);
 	if (ret != font->type1_length) {
 	    status = _cairo_error (CAIRO_STATUS_READ_ERROR);
 	    goto fail;
commit bc872a5f5fb9b6318dc78d132da46a6b201f75c7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Oct 15 10:21:05 2008 +0100

    [xlib] Handle 4,20,24,28 depth XImages
    
    Bug 9102 cairo doesn't support 24 bits per pixel mode on X11
    (https://bugs.freedesktop.org/show_bug.cgi?id=9102)
    is a reminder that that we need to support many obscure XImage formats.
    With Carl's and Behdad's work to support psuedocolor we have a mechanism
    in place to handle any format that is not natively handled by pixman. The
    only piece we were missing was extending the swapper to handle all-known
    formats and putting in defensive checks that pixels were correctly aligned
    in accordance with pixman's requirements.

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 3cb4ccc..68adb6a 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -154,7 +154,7 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t		*pixman_image,
     return &surface->base;
 }
 
-cairo_int_status_t
+cairo_bool_t
 _pixman_format_from_masks (cairo_format_masks_t *masks,
 			   pixman_format_code_t *format_ret)
 {
@@ -176,13 +176,13 @@ _pixman_format_from_masks (cairo_format_masks_t *masks,
     } else if (masks->alpha_mask) {
 	format_type = PIXMAN_TYPE_A;
     } else {
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+	return FALSE;
     }
 
     format = PIXMAN_FORMAT (masks->bpp, format_type, a, r, g, b);
 
     if (! pixman_format_supported_destination (format))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+	return FALSE;
 
     /* Sanity check that we got out of PIXMAN_FORMAT exactly what we
      * expected. This avoid any problems from something bizarre like
@@ -195,11 +195,11 @@ _pixman_format_from_masks (cairo_format_masks_t *masks,
 	 masks->green_mask != format_masks.green_mask ||
 	 masks->blue_mask  != format_masks.blue_mask)
      {
-	 return CAIRO_INT_STATUS_UNSUPPORTED;
+	 return FALSE;
      }
 
     *format_ret = format;
-    return CAIRO_STATUS_SUCCESS;
+    return TRUE;
 }
 
 /* A mask consisting of N bits set to 1. */
@@ -266,8 +266,7 @@ _cairo_image_surface_create_with_masks (unsigned char	       *data,
     cairo_int_status_t status;
     pixman_format_code_t pixman_format;
 
-    status = _pixman_format_from_masks (masks, &pixman_format);
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+    if (! _pixman_format_from_masks (masks, &pixman_format)) {
 	fprintf (stderr,
 		 "Error: Cairo %s does not yet support the requested image format:\n"
 		 "\tDepth: %d\n"
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index d22337a..0d80536 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -343,7 +343,7 @@ _swap_ximage_2bytes (XImage *ximage)
     char *line = ximage->data;
 
     for (j = ximage->height; j; j--) {
-	uint16_t *p = (uint16_t *)line;
+	uint16_t *p = (uint16_t *) line;
 	for (i = ximage->width; i; i--) {
 	    *p = bswap_16 (*p);
 	    p++;
@@ -354,13 +354,33 @@ _swap_ximage_2bytes (XImage *ximage)
 }
 
 static void
+_swap_ximage_3bytes (XImage *ximage)
+{
+    int i, j;
+    char *line = ximage->data;
+
+    for (j = ximage->height; j; j--) {
+	uint8_t *p = (uint8_t *) line;
+	for (i = ximage->width; i; i--) {
+	    uint8_t tmp;
+	    tmp = p[2];
+	    p[2] = p[0];
+	    p[0] = tmp;
+	    p += 3;
+	}
+
+	line += ximage->bytes_per_line;
+    }
+}
+
+static void
 _swap_ximage_4bytes (XImage *ximage)
 {
     int i, j;
     char *line = ximage->data;
 
     for (j = ximage->height; j; j--) {
-	uint32_t *p = (uint32_t *)line;
+	uint32_t *p = (uint32_t *) line;
 	for (i = ximage->width; i; i--) {
 	    *p = bswap_32 (*p);
 	    p++;
@@ -371,6 +391,23 @@ _swap_ximage_4bytes (XImage *ximage)
 }
 
 static void
+_swap_ximage_nibbles (XImage *ximage)
+{
+    int i, j;
+    char *line = ximage->data;
+
+    for (j = ximage->height; j; j--) {
+	uint8_t *p = (uint8_t *) line;
+	for (i = (ximage->width + 1) / 2; i; i--) {
+	    *p = ((*p >> 4) & 0xf) | ((*p << 4) & ~0xf);
+	    p++;
+	}
+
+	line += ximage->bytes_per_line;
+    }
+}
+
+static void
 _swap_ximage_bits (XImage *ximage)
 {
     int i, j;
@@ -402,7 +439,8 @@ _swap_ximage_to_native (XImage *ximage)
     int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;
 
     if (ximage->bits_per_pixel == 1 &&
-	ximage->bitmap_bit_order != native_byte_order) {
+	ximage->bitmap_bit_order != native_byte_order)
+    {
 	_swap_ximage_bits (ximage);
 	if (ximage->bitmap_bit_order == ximage->byte_order)
 	    return;
@@ -415,25 +453,32 @@ _swap_ximage_to_native (XImage *ximage)
     case 1:
 	unit_bytes = ximage->bitmap_unit / 8;
 	break;
+    case 4:
+	_swap_ximage_nibbles (ximage);
+	/* fall-through */
     case 8:
     case 16:
+    case 20:
+    case 24:
+    case 28:
+    case 30:
     case 32:
-	unit_bytes = ximage->bits_per_pixel / 8;
+	unit_bytes = (ximage->bits_per_pixel + 7) / 8;
 	break;
     default:
-        /* This could be hit on some uncommon but possible cases,
-	 * such as bpp=4. These are cases that libpixman can't deal
-	 * with in any case.
-	 */
+        /* This could be hit on some rare but possible cases. */
 	ASSERT_NOT_REACHED;
     }
 
     switch (unit_bytes) {
     case 1:
-	return;
+	break;
     case 2:
 	_swap_ximage_2bytes (ximage);
 	break;
+    case 3:
+	_swap_ximage_3bytes (ximage);
+	break;
     case 4:
 	_swap_ximage_4bytes (ximage);
 	break;
@@ -676,8 +721,11 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
     xlib_masks.green_mask = surface->g_mask;
     xlib_masks.blue_mask = surface->b_mask;
 
-    status = _pixman_format_from_masks (&xlib_masks, &pixman_format);
-    if (xlib_masks.bpp >= 24 &&status == CAIRO_STATUS_SUCCESS) {
+    if (_pixman_format_from_masks (&xlib_masks, &pixman_format) &&
+	xlib_masks.bpp >= 24 &&
+	ximage->bitmap_unit == 32 &&
+	ximage->bitmap_pad == 32)
+    {
 	image = (cairo_image_surface_t*)
 	    _cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage->data,
 							    pixman_format,
diff --git a/src/cairoint.h b/src/cairoint.h
index afdcd4d..960c38f 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1990,7 +1990,7 @@ cairo_private cairo_surface_t *
 _cairo_image_surface_create_for_pixman_image (pixman_image_t		*pixman_image,
 					      pixman_format_code_t	 pixman_format);
 
-cairo_private cairo_int_status_t
+cairo_private cairo_bool_t
 _pixman_format_from_masks (cairo_format_masks_t *masks,
 			   pixman_format_code_t *format_ret);
 


More information about the cairo-commit mailing list