[cairo] [PATCH v8 12/71] image: typecasting helpers

Enrico Weigelt, metux IT consult enrico.weigelt at gr13.net
Thu Jun 30 15:45:50 UTC 2016


Introduce helpers for typecasting from abstract surface to the
actual image surface type.

This patch is also going to be needed by other backends utilizing
the image surface internally.

Signed-off-by: Enrico Weigelt, metux IT consult <enrico.weigelt at gr13.net>
---
 src/cairo-image-compositor.c            |  8 ++---
 src/cairo-image-surface-private.h       |  8 ++++-
 src/cairo-image-surface.c               | 53 +++++++++++++++++----------------
 src/win32/cairo-win32-display-surface.c |  8 ++---
 src/win32/cairo-win32-gdi-compositor.c  |  6 ++--
 5 files changed, 45 insertions(+), 38 deletions(-)

diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index 48072f8..ccc403c 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -2080,10 +2080,10 @@ mono_renderer_init (cairo_image_span_renderer_t	*r,
 		 (dst->base.is_clear || (dst->base.content & CAIRO_CONTENT_ALPHA) == 0))) &&
 	       composite->source_pattern.base.type == CAIRO_PATTERN_TYPE_SURFACE &&
 	       composite->source_pattern.surface.surface->backend->type == CAIRO_SURFACE_TYPE_IMAGE &&
-	       to_image_surface(composite->source_pattern.surface.surface)->format == dst->format)
+	       _cairo_surface_cast_image (composite->source_pattern.surface.surface)->format == dst->format)
     {
        cairo_image_surface_t *src =
-	   to_image_surface(composite->source_pattern.surface.surface);
+	   _cairo_surface_cast_image (composite->source_pattern.surface.surface);
        int tx, ty;
 
 	if (_cairo_matrix_is_integer_translation(&composite->source_pattern.base.matrix,
@@ -2850,10 +2850,10 @@ inplace_renderer_init (cairo_image_span_renderer_t	*r,
 		 (dst->base.is_clear || (dst->base.content & CAIRO_CONTENT_ALPHA) == 0))) &&
 	       composite->source_pattern.base.type == CAIRO_PATTERN_TYPE_SURFACE &&
 	       composite->source_pattern.surface.surface->backend->type == CAIRO_SURFACE_TYPE_IMAGE &&
-	       to_image_surface(composite->source_pattern.surface.surface)->format == dst->format)
+	       _cairo_surface_cast_image (composite->source_pattern.surface.surface)->format == dst->format)
     {
        cairo_image_surface_t *src =
-	   to_image_surface(composite->source_pattern.surface.surface);
+	   _cairo_surface_cast_image (composite->source_pattern.surface.surface);
        int tx, ty;
 
 	if (_cairo_matrix_is_integer_translation(&composite->source_pattern.base.matrix,
diff --git a/src/cairo-image-surface-private.h b/src/cairo-image-surface-private.h
index 8ca694c..b2ca46b 100644
--- a/src/cairo-image-surface-private.h
+++ b/src/cairo-image-surface-private.h
@@ -78,7 +78,6 @@ struct _cairo_image_surface {
     unsigned transparency : 2;
     unsigned color : 2;
 };
-#define to_image_surface(S) ((cairo_image_surface_t *)(S))
 
 /* A wrapper for holding pixman images returned by create_for_pattern */
 typedef struct _cairo_image_source {
@@ -88,6 +87,13 @@ typedef struct _cairo_image_source {
     unsigned is_opaque_solid : 1;
 } cairo_image_source_t;
 
+static cairo_always_inline cairo_image_surface_t *
+_cairo_surface_cast_image ( cairo_surface_t *surface )
+{
+    assert (surface->type == CAIRO_SURFACE_TYPE_IMAGE);
+    return cairo_container_of (surface, cairo_image_surface_t, base);
+}
+
 cairo_private extern const cairo_surface_backend_t _cairo_image_surface_backend;
 cairo_private extern const cairo_surface_backend_t _cairo_image_source_backend;
 
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 1571c54..cdbe00d 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -403,7 +403,7 @@ cairo_image_surface_create (cairo_format_t	format,
 }
 slim_hidden_def (cairo_image_surface_create);
 
-    cairo_surface_t *
+cairo_surface_t *
 _cairo_image_surface_create_with_content (cairo_content_t	content,
 					  int			width,
 					  int			height)
@@ -562,7 +562,7 @@ slim_hidden_def (cairo_image_surface_create_for_data);
 unsigned char *
 cairo_image_surface_get_data (cairo_surface_t *surface)
 {
-    cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
+    cairo_image_surface_t *image_surface = _cairo_surface_cast_image (surface);
 
     if (! _cairo_surface_is_image (surface)) {
 	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
@@ -586,7 +586,7 @@ slim_hidden_def (cairo_image_surface_get_data);
 cairo_format_t
 cairo_image_surface_get_format (cairo_surface_t *surface)
 {
-    cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
+    cairo_image_surface_t *image_surface = _cairo_surface_cast_image (surface);
 
     if (! _cairo_surface_is_image (surface)) {
 	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
@@ -610,7 +610,7 @@ slim_hidden_def (cairo_image_surface_get_format);
 int
 cairo_image_surface_get_width (cairo_surface_t *surface)
 {
-    cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
+    cairo_image_surface_t *image_surface = _cairo_surface_cast_image (surface);
 
     if (! _cairo_surface_is_image (surface)) {
 	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
@@ -634,7 +634,7 @@ slim_hidden_def (cairo_image_surface_get_width);
 int
 cairo_image_surface_get_height (cairo_surface_t *surface)
 {
-    cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
+    cairo_image_surface_t *image_surface = _cairo_surface_cast_image (surface);
 
     if (! _cairo_surface_is_image (surface)) {
 	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
@@ -661,8 +661,7 @@ slim_hidden_def (cairo_image_surface_get_height);
 int
 cairo_image_surface_get_stride (cairo_surface_t *surface)
 {
-
-    cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
+    cairo_image_surface_t *image_surface = _cairo_surface_cast_image (surface);
 
     if (! _cairo_surface_is_image (surface)) {
 	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
@@ -673,7 +672,7 @@ cairo_image_surface_get_stride (cairo_surface_t *surface)
 }
 slim_hidden_def (cairo_image_surface_get_stride);
 
-    cairo_format_t
+cairo_format_t
 _cairo_format_from_content (cairo_content_t content)
 {
     switch (content) {
@@ -689,7 +688,7 @@ _cairo_format_from_content (cairo_content_t content)
     return CAIRO_FORMAT_INVALID;
 }
 
-    cairo_content_t
+cairo_content_t
 _cairo_content_from_format (cairo_format_t format)
 {
     switch (format) {
@@ -712,7 +711,7 @@ _cairo_content_from_format (cairo_format_t format)
     return CAIRO_CONTENT_COLOR_ALPHA;
 }
 
-    int
+int
 _cairo_format_bits_per_pixel (cairo_format_t format)
 {
     switch (format) {
@@ -739,7 +738,7 @@ _cairo_image_surface_create_similar (void	       *abstract_other,
 				     int		width,
 				     int		height)
 {
-    cairo_image_surface_t *other = abstract_other;
+    cairo_image_surface_t *other = _cairo_surface_cast_image (abstract_other);
 
     TRACE ((stderr, "%s (other=%u)\n", __FUNCTION__, other->base.unique_id));
 
@@ -760,7 +759,7 @@ _cairo_image_surface_create_similar (void	       *abstract_other,
 cairo_surface_t *
 _cairo_image_surface_snapshot (void *abstract_surface)
 {
-    cairo_image_surface_t *image = abstract_surface;
+    cairo_image_surface_t *image = _cairo_surface_cast_image (abstract_surface);
     cairo_image_surface_t *clone;
 
     /* If we own the image, we can simply steal the memory for the snapshot */
@@ -808,7 +807,7 @@ cairo_image_surface_t *
 _cairo_image_surface_map_to_image (void *abstract_other,
 				   const cairo_rectangle_int_t *extents)
 {
-    cairo_image_surface_t *other = abstract_other;
+    cairo_image_surface_t *other = _cairo_surface_cast_image (abstract_other);
     cairo_surface_t *surface;
     uint8_t *data;
 
@@ -840,7 +839,7 @@ _cairo_image_surface_unmap_image (void *abstract_surface,
 cairo_status_t
 _cairo_image_surface_finish (void *abstract_surface)
 {
-    cairo_image_surface_t *surface = abstract_surface;
+    cairo_image_surface_t *surface = _cairo_surface_cast_image (abstract_surface);
 
     if (surface->pixman_image) {
 	pixman_image_unref (surface->pixman_image);
@@ -871,7 +870,7 @@ cairo_surface_t *
 _cairo_image_surface_source (void			*abstract_surface,
 			     cairo_rectangle_int_t	*extents)
 {
-    cairo_image_surface_t *surface = abstract_surface;
+    cairo_image_surface_t *surface = _cairo_surface_cast_image (abstract_surface);
 
     if (extents) {
 	extents->x = extents->y = 0;
@@ -887,7 +886,7 @@ _cairo_image_surface_acquire_source_image (void                    *abstract_sur
 					   cairo_image_surface_t  **image_out,
 					   void                   **image_extra)
 {
-    *image_out = abstract_surface;
+    *image_out = _cairo_surface_cast_image (abstract_surface);
     *image_extra = NULL;
 
     return CAIRO_STATUS_SUCCESS;
@@ -905,7 +904,7 @@ cairo_bool_t
 _cairo_image_surface_get_extents (void			  *abstract_surface,
 				  cairo_rectangle_int_t   *rectangle)
 {
-    cairo_image_surface_t *surface = abstract_surface;
+    cairo_image_surface_t *surface = _cairo_surface_cast_image (abstract_surface);
 
     rectangle->x = 0;
     rectangle->y = 0;
@@ -921,7 +920,7 @@ _cairo_image_surface_paint (void			*abstract_surface,
 			    const cairo_pattern_t	*source,
 			    const cairo_clip_t		*clip)
 {
-    cairo_image_surface_t *surface = abstract_surface;
+    cairo_image_surface_t *surface = _cairo_surface_cast_image (abstract_surface);
 
     TRACE ((stderr, "%s (surface=%d)\n",
 	    __FUNCTION__, surface->base.unique_id));
@@ -937,7 +936,7 @@ _cairo_image_surface_mask (void				*abstract_surface,
 			   const cairo_pattern_t	*mask,
 			   const cairo_clip_t		*clip)
 {
-    cairo_image_surface_t *surface = abstract_surface;
+    cairo_image_surface_t *surface = _cairo_surface_cast_image (abstract_surface);
 
     TRACE ((stderr, "%s (surface=%d)\n",
 	    __FUNCTION__, surface->base.unique_id));
@@ -958,7 +957,7 @@ _cairo_image_surface_stroke (void			*abstract_surface,
 			     cairo_antialias_t		 antialias,
 			     const cairo_clip_t		*clip)
 {
-    cairo_image_surface_t *surface = abstract_surface;
+    cairo_image_surface_t *surface = _cairo_surface_cast_image (abstract_surface);
 
     TRACE ((stderr, "%s (surface=%d)\n",
 	    __FUNCTION__, surface->base.unique_id));
@@ -979,7 +978,7 @@ _cairo_image_surface_fill (void				*abstract_surface,
 			   cairo_antialias_t		 antialias,
 			   const cairo_clip_t		*clip)
 {
-    cairo_image_surface_t *surface = abstract_surface;
+    cairo_image_surface_t *surface = _cairo_surface_cast_image (abstract_surface);
 
     TRACE ((stderr, "%s (surface=%d)\n",
 	    __FUNCTION__, surface->base.unique_id));
@@ -999,7 +998,7 @@ _cairo_image_surface_glyphs (void			*abstract_surface,
 			     cairo_scaled_font_t	*scaled_font,
 			     const cairo_clip_t		*clip)
 {
-    cairo_image_surface_t *surface = abstract_surface;
+    cairo_image_surface_t *surface = _cairo_surface_cast_image (abstract_surface);
 
     TRACE ((stderr, "%s (surface=%d)\n",
 	    __FUNCTION__, surface->base.unique_id));
@@ -1306,7 +1305,7 @@ _cairo_image_surface_clone_subimage (cairo_surface_t             *surface,
 						extents->width,
 						extents->height);
     if (image->status)
-	return to_image_surface (image);
+	return _cairo_surface_cast_image (image);
 
     /* TODO: check me with non-identity device_transform. Should we
      * clone the scaling, too? */
@@ -1333,12 +1332,14 @@ _cairo_image_surface_clone_subimage (cairo_surface_t             *surface,
      * we need to make sure the parent surface obeys the reference counting
      * semantics and is consistent for all callers.
      */
-    _cairo_image_surface_set_parent (to_image_surface (image),
+    _cairo_image_surface_set_parent (_cairo_surface_cast_image (image),
 				     cairo_surface_reference (surface));
 
-    return to_image_surface (image);
+    return _cairo_surface_cast_image (image);
 
 error:
     cairo_surface_destroy (image);
-    return to_image_surface (_cairo_surface_create_in_error (status));
+
+    // FIXME: this is a very brutal typecast and potentially dangerous
+    return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);
 }
diff --git a/src/win32/cairo-win32-display-surface.c b/src/win32/cairo-win32-display-surface.c
index 025b2c9..67bee6d 100644
--- a/src/win32/cairo-win32-display-surface.c
+++ b/src/win32/cairo-win32-display-surface.c
@@ -316,7 +316,7 @@ _cairo_win32_display_surface_create_for_dc (HDC             original_dc,
     if (status)
 	goto FAIL;
 
-    _cairo_image_surface_set_parent (to_image_surface(surface->image),
+    _cairo_image_surface_set_parent (_cairo_surface_cast_image(surface->image),
 				     &surface->win32.base);
 
     surface->win32.format = format;
@@ -416,10 +416,10 @@ _cairo_win32_display_surface_finish (void *abstract_surface)
 {
     cairo_win32_display_surface_t *surface = abstract_surface;
 
-    if (surface->image && to_image_surface(surface->image)->parent) {
-	assert (to_image_surface(surface->image)->parent == &surface->win32.base);
+    if (surface->image && _cairo_surface_cast_image (surface->image)->parent) {
+	assert (_cairo_surface_cast_image(surface->image)->parent == &surface->win32.base);
 	/* Unhook ourselves first to avoid the double-unref from the image */
-	to_image_surface(surface->image)->parent = NULL;
+	_cairo_surface_cast_image (surface->image)->parent = NULL;
 	cairo_surface_finish (surface->image);
 	cairo_surface_destroy (surface->image);
     }
diff --git a/src/win32/cairo-win32-gdi-compositor.c b/src/win32/cairo-win32-gdi-compositor.c
index 073e889..3c4b750 100644
--- a/src/win32/cairo-win32-gdi-compositor.c
+++ b/src/win32/cairo-win32-gdi-compositor.c
@@ -219,7 +219,7 @@ copy_boxes (cairo_win32_display_surface_t *dst,
     pattern = (const cairo_surface_pattern_t *) source;
     surface = _cairo_surface_get_source (pattern->surface, &cb.limit);
     if (surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
-	surface = to_image_surface(surface)->parent;
+	surface = _cairo_surface_cast_image (surface)->parent;
 	if (surface == NULL)
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
     }
@@ -285,7 +285,7 @@ upload_boxes (cairo_win32_display_surface_t *dst,
 	if (status)
 	    return status;
     } else
-	image = to_image_surface(surface);
+	image = _cairo_surface_cast_image (surface);
 
     status = CAIRO_INT_STATUS_UNSUPPORTED;
     if (!(image->format == CAIRO_FORMAT_ARGB32 ||
@@ -342,7 +342,7 @@ alpha_blend_boxes (cairo_win32_display_surface_t *dst,
     pattern = (const cairo_surface_pattern_t *) source;
     surface = _cairo_surface_get_source (pattern->surface, &cb.limit);
     if (surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
-	surface = to_image_surface(surface)->parent;
+	surface = _cairo_surface_cast_image (surface)->parent;
 	if (surface == NULL)
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
     }
-- 
2.6.4.442.g545299f



More information about the cairo mailing list