[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