[cairo-commit] 4 commits - src/cairo.h src/cairo-surface.c src/cairo-xlib-xcb-surface.c test/map-to-image.c
Uli Schlachter
psychon at kemper.freedesktop.org
Mon Aug 8 12:07:23 PDT 2011
src/cairo-surface.c | 11 +++++++++++
src/cairo-xlib-xcb-surface.c | 4 ++++
src/cairo.h | 1 +
test/map-to-image.c | 42 ++++++++++++++++++++++++++++++++++++------
4 files changed, 52 insertions(+), 6 deletions(-)
New commits:
commit 7b97533221aa5713168b9ddefb4a647cff98c510
Author: Uli Schlachter <psychon at znc.in>
Date: Fri Aug 5 21:32:03 2011 +0200
map-to-image: Handle non-32bpp formats
Fixes: map-all-to-image, map-bit-to-image for image16
Signed-off-by: Uli Schlachter <psychon at znc.in>
diff --git a/test/map-to-image.c b/test/map-to-image.c
index 8528fa0..b7d6df8 100644
--- a/test/map-to-image.c
+++ b/test/map-to-image.c
@@ -30,7 +30,30 @@
#define HEIGHT 3
/* A single, black pixel */
-static const uint32_t black_pixel = 0xff000000;
+static const uint32_t black_pixel_argb = 0xff000000;
+static const uint32_t black_pixel = 0x00000000;
+
+static cairo_bool_t
+set_pixel_black(uint8_t *data, int stride,
+ cairo_format_t format, int x, int y)
+{
+ switch (format) {
+ case CAIRO_FORMAT_ARGB32:
+ case CAIRO_FORMAT_RGB24:
+ *(uint32_t *)(data + y * stride + 4*x) = black_pixel_argb;
+ break;
+ case CAIRO_FORMAT_RGB16_565:
+ *(uint16_t *)(data + y * stride + 2*x) = black_pixel;
+ break;
+ case CAIRO_FORMAT_RGB30:
+ case CAIRO_FORMAT_A8:
+ case CAIRO_FORMAT_A1:
+ case CAIRO_FORMAT_INVALID:
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
static cairo_test_status_t
all (cairo_t *cr, int width, int height)
@@ -38,6 +61,7 @@ all (cairo_t *cr, int width, int height)
cairo_surface_t *surface;
uint8_t *data;
int stride;
+ cairo_format_t format;
int i, j;
/* Fill background white */
@@ -46,12 +70,14 @@ all (cairo_t *cr, int width, int height)
surface = cairo_surface_map_to_image (cairo_get_target (cr), NULL);
cairo_surface_flush (surface);
+ format = cairo_image_surface_get_format (surface);
stride = cairo_image_surface_get_stride (surface);
data = cairo_image_surface_get_data (surface);
if (data) {
- for (j = 0; j < HEIGHT; j++)
- for (i = 0; i < WIDTH; i++)
- *(uint32_t *)(data + j * stride + 4*i) = black_pixel;
+ for (j = 0; j < HEIGHT; j++)
+ for (i = 0; i < WIDTH; i++)
+ if (! set_pixel_black (data, stride, format, i, j))
+ return CAIRO_TEST_FAILURE;
}
cairo_surface_mark_dirty (surface);
cairo_surface_unmap_image (cairo_get_target (cr), surface);
@@ -64,6 +90,7 @@ bit (cairo_t *cr, int width, int height)
{
cairo_surface_t *surface;
cairo_rectangle_t extents;
+ cairo_format_t format;
uint8_t *data;
extents.x = extents.y = extents.width = extents.height = 1;
@@ -75,8 +102,11 @@ bit (cairo_t *cr, int width, int height)
surface = cairo_surface_map_to_image (cairo_get_target (cr), &extents);
cairo_surface_flush (surface);
data = cairo_image_surface_get_data (surface);
- if (data)
- *(uint32_t *)data = black_pixel;
+ format = cairo_image_surface_get_format (surface);
+ if (data) {
+ if (! set_pixel_black (data, 0, format, 0, 0))
+ return CAIRO_TEST_FAILURE;
+ }
cairo_surface_mark_dirty (surface);
cairo_surface_unmap_image (cairo_get_target (cr), surface);
commit 5a26018313f40a832a1ec378c1a137ee4a852742
Author: Uli Schlachter <psychon at znc.in>
Date: Fri Aug 5 22:03:19 2011 +0200
map_to_image: Verify the given extents
User shouldn't be able to use extents that are not completely inside of the
surface's extents.
Signed-off-by: Uli Schlachter <psychon at znc.in>
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index b699393..71f8aea 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -611,7 +611,18 @@ cairo_surface_map_to_image (cairo_surface_t *surface,
if (unlikely (! surface->backend->get_extents (surface, &rect)))
return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
} else {
+ cairo_rectangle_int_t surface_extents;
_cairo_rectangle_int_from_double (&rect, extents);
+
+ /* If this surface is bounded, we can't map parts
+ * that are outside of it. */
+ if (likely (surface->backend->get_extents (surface, &surface_extents))) {
+ if (unlikely (rect.x < surface_extents.x ||
+ rect.y < surface_extents.y ||
+ rect.x + rect.width > surface_extents.x + surface_extents.width ||
+ rect.y + rect.height > surface_extents.y + surface_extents.height))
+ return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
+ }
}
image = NULL;
commit 03cda5c0e51ec6ef78ee56cb4d72b6213d6d89e4
Author: Uli Schlachter <psychon at znc.in>
Date: Fri Aug 5 21:07:38 2011 +0200
xlib-xcb: Fix a double free in surface_unmap
cairo_surface_unmap_image() destroys the image that was passed to it. Since
xlib-xcb calls cairo_surface_unmap_image() again for the underlying xcb surface,
the surface was destroyed twice.
Work around this problem by incrementing the image's reference count via
cairo_surface_reference().
No idea why I didn't catch this problem when implementing these functions, I'm
sure I ran the relevant tests. :-(
lt-cairo-test-suite: cairo-surface.c:853: cairo_surface_destroy: Assertion
`((*&(&surface->ref_count)->ref_count) > 0)' failed.
Fixes: map-to-image-fill map-bit-to-image map-all-to-image
Signed-off-by: Uli Schlachter <psychon at znc.in>
diff --git a/src/cairo-xlib-xcb-surface.c b/src/cairo-xlib-xcb-surface.c
index aa74223..6da44a1 100644
--- a/src/cairo-xlib-xcb-surface.c
+++ b/src/cairo-xlib-xcb-surface.c
@@ -134,6 +134,10 @@ _cairo_xlib_xcb_surface_unmap (void *abstract_surface,
{
cairo_xlib_xcb_surface_t *surface = abstract_surface;
+ /* cairo_surface_unmap_image destroys the surface, so get a new reference
+ * for it to destroy.
+ */
+ cairo_surface_reference (&image->base);
cairo_surface_unmap_image (&surface->xcb->base, &image->base);
return cairo_surface_status (&surface->xcb->base);
}
commit 73e93078554849673c54d82b229f76bfb918b7d0
Author: Uli Schlachter <psychon at znc.in>
Date: Thu Aug 4 22:51:37 2011 +0200
cairo.h: Document CAIRO_DEVICE_TYPE_INVALID
Signed-off-by: Uli Schlachter <psychon at znc.in>
diff --git a/src/cairo.h b/src/cairo.h
index 1eb30d7..9d788cc 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -1999,6 +1999,7 @@ cairo_device_reference (cairo_device_t *device);
* @CAIRO_DEVICE_TYPE_XCB: The device is of type xcb
* @CAIRO_DEVICE_TYPE_XLIB: The device is of type xlib
* @CAIRO_DEVICE_TYPE_XML: The device is of type XML
+ * @CAIRO_DEVICE_TYPE_INVALID: The device is invalid
*
* #cairo_device_type_t is used to describe the type of a given
* device. The devices types are also known as "backends" within cairo.
More information about the cairo-commit
mailing list