summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cairo-analysis-surface.c2
-rw-r--r--src/cairo-cogl-surface.c1
-rw-r--r--src/cairo-directfb-surface.c1
-rw-r--r--src/cairo-gl-surface.c14
-rw-r--r--src/cairo-image-source.c12
-rw-r--r--src/cairo-image-surface-private.h5
-rw-r--r--src/cairo-image-surface.c14
-rw-r--r--src/cairo-mask-compositor.c25
-rw-r--r--src/cairo-os2-surface.c1
-rw-r--r--src/cairo-paginated-surface.c9
-rw-r--r--src/cairo-pattern-private.h8
-rw-r--r--src/cairo-pdf-surface.c1
-rw-r--r--src/cairo-ps-surface.c1
-rw-r--r--src/cairo-qt-surface.cpp1
-rw-r--r--src/cairo-quartz-image-surface.c1
-rw-r--r--src/cairo-recording-surface.c2
-rw-r--r--src/cairo-script-surface.c14
-rw-r--r--src/cairo-spans-compositor.c18
-rw-r--r--src/cairo-surface-backend-private.h8
-rw-r--r--src/cairo-surface-observer.c9
-rw-r--r--src/cairo-surface-private.h4
-rw-r--r--src/cairo-surface-snapshot.c9
-rw-r--r--src/cairo-surface-subsurface.c14
-rw-r--r--src/cairo-surface.c16
-rw-r--r--src/cairo-svg-surface.c1
-rw-r--r--src/cairo-tee-surface.c9
-rw-r--r--src/cairo-traps-compositor.c26
-rw-r--r--src/cairo-type3-glyph-surface.c1
-rw-r--r--src/cairo-vg-surface.c1
-rw-r--r--src/cairo-win32-printing-surface.c1
-rw-r--r--src/cairo-win32-surface.c1
-rw-r--r--src/cairo-xcb-surface.c14
-rw-r--r--src/cairo-xlib-source.c17
-rw-r--r--src/cairo-xlib-surface.c14
-rw-r--r--src/cairo-xlib-xcb-surface.c9
-rw-r--r--src/cairo-xml-surface.c1
-rw-r--r--src/drm/cairo-drm-gallium-surface.c1
-rw-r--r--src/drm/cairo-drm-i915-surface.c2
-rw-r--r--src/drm/cairo-drm-i965-surface.c2
-rw-r--r--src/drm/cairo-drm-intel-surface.c3
-rw-r--r--src/drm/cairo-drm-radeon-surface.c3
-rw-r--r--src/test-compositor-surface.c1
-rw-r--r--src/test-null-compositor-surface.c1
-rw-r--r--src/test-paginated-surface.c1
44 files changed, 232 insertions, 67 deletions
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index d9edcd724..895d82b78 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -702,6 +702,7 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = {
NULL, /* map_to_image */
NULL, /* unmap */
+ NULL, /* source */
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* snapshot */
@@ -895,6 +896,7 @@ static const cairo_surface_backend_t cairo_null_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image*/
+ NULL, /* source */
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* snapshot */
diff --git a/src/cairo-cogl-surface.c b/src/cairo-cogl-surface.c
index 3f9a782da..7326284a6 100644
--- a/src/cairo-cogl-surface.c
+++ b/src/cairo-cogl-surface.c
@@ -2463,6 +2463,7 @@ const cairo_surface_backend_t _cairo_cogl_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_default_source,
_cairo_cogl_surface_acquire_source_image,
_cairo_cogl_surface_release_source_image,
NULL, /* snapshot */
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index 46c096082..dd830f062 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -1835,6 +1835,7 @@ _cairo_directfb_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_default_source,
_cairo_directfb_surface_acquire_source_image,/*acquire_source_image*/
_cairo_directfb_surface_release_source_image,/*release_source_image*/
_cairo_directfb_surface_acquire_dest_image,/*acquire_dest_image*/
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 7601b6ad6..c0d768aab 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -1078,6 +1078,19 @@ _cairo_gl_surface_map_to_image (void *abstract_surface,
return &image->base;
}
+static cairo_surface_t *
+_cairo_gl_surface_source (void *abstract_surface,
+ cairo_rectangle_int_t *extents)
+{
+ cairo_gl_surface_t *surface = abstract_surface;
+
+ extents->x = extents->y = 0;
+ extents->width = surface->width;
+ extents->height = surface->height;
+
+ return &surface->base;
+}
+
static cairo_status_t
_cairo_gl_surface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -1249,6 +1262,7 @@ static const cairo_surface_backend_t _cairo_gl_surface_backend = {
_cairo_gl_surface_map_to_image,
_cairo_gl_surface_unmap_image,
+ _cairo_gl_surface_source,
_cairo_gl_surface_acquire_source_image,
_cairo_gl_surface_release_source_image,
NULL, /* snapshot */
diff --git a/src/cairo-image-source.c b/src/cairo-image-source.c
index 047a049e3..2c9437930 100644
--- a/src/cairo-image-source.c
+++ b/src/cairo-image-source.c
@@ -609,15 +609,9 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
*ix = *iy = 0;
- source = pattern->surface;
- if (_cairo_surface_is_subsurface (source))
- source = _cairo_surface_subsurface_get_target_with_offset (source, &tx, &ty);
- if (_cairo_surface_is_snapshot (source))
- source = _cairo_surface_snapshot_get_target (source);
- if (_cairo_surface_is_observer (source))
- source = _cairo_surface_observer_get_target (source);
- if (_cairo_surface_is_paginated (source))
- source = _cairo_paginated_surface_get_target (source);
+ source = _cairo_pattern_get_source (pattern, &limit);
+ tx = limit.x;
+ ty = limit.y;
extend = pattern->base.extend;
if (_cairo_surface_get_extents (source, &limit)) {
diff --git a/src/cairo-image-surface-private.h b/src/cairo-image-surface-private.h
index 2777e2f3d..d580d8943 100644
--- a/src/cairo-image-surface-private.h
+++ b/src/cairo-image-surface-private.h
@@ -97,6 +97,11 @@ _cairo_image_surface_map_to_image (void *abstract_other,
cairo_private cairo_int_status_t
_cairo_image_surface_unmap_image (void *abstract_surface,
cairo_image_surface_t *image);
+
+cairo_private cairo_surface_t *
+_cairo_image_surface_source (void *abstract_surface,
+ cairo_rectangle_int_t *extents);
+
cairo_private cairo_status_t
_cairo_image_surface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 6adbdd61f..212e2b592 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -819,6 +819,19 @@ _cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface)
surface->owns_data = TRUE;
}
+cairo_surface_t *
+_cairo_image_surface_source (void *abstract_surface,
+ cairo_rectangle_int_t *extents)
+{
+ cairo_image_surface_t *surface = abstract_surface;
+
+ extents->x = extents->y = 0;
+ extents->width = surface->width;
+ extents->height = surface->height;
+
+ return &surface->base;
+}
+
cairo_status_t
_cairo_image_surface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -948,6 +961,7 @@ const cairo_surface_backend_t _cairo_image_surface_backend = {
_cairo_image_surface_map_to_image,
_cairo_image_surface_unmap_image,
+ _cairo_image_surface_source,
_cairo_image_surface_acquire_source_image,
_cairo_image_surface_release_source_image,
_cairo_image_surface_snapshot,
diff --git a/src/cairo-mask-compositor.c b/src/cairo-mask-compositor.c
index b34ffa257..807ba996c 100644
--- a/src/cairo-mask-compositor.c
+++ b/src/cairo-mask-compositor.c
@@ -778,39 +778,30 @@ upload_boxes (const cairo_mask_compositor_t *compositor,
{
cairo_surface_t *dst = extents->surface;
const cairo_pattern_t *source = &extents->source_pattern.base;
- const cairo_surface_pattern_t *pattern;
cairo_surface_t *src;
cairo_rectangle_int_t limit;
cairo_int_status_t status;
int tx, ty;
- pattern = (const cairo_surface_pattern_t *) source;
- src = pattern->surface;
+ src = _cairo_pattern_get_source ((cairo_surface_pattern_t *)source, &limit);
if (!(src->type == CAIRO_SURFACE_TYPE_IMAGE || src->type == dst->type))
return CAIRO_INT_STATUS_UNSUPPORTED;
if (! _cairo_matrix_is_integer_translation (&source->matrix, &tx, &ty))
return CAIRO_INT_STATUS_UNSUPPORTED;
- if (_cairo_surface_is_snapshot (src))
- src = _cairo_surface_snapshot_get_target (src);
- if (_cairo_surface_is_observer (src))
- src = _cairo_surface_observer_get_target (src);
- if (_cairo_surface_is_subsurface (src)) {
- _cairo_surface_subsurface_offset (src, &tx, &ty);
- src = _cairo_surface_subsurface_get_target (src);
- }
-
/* Check that the data is entirely within the image */
- if (extents->bounded.x + tx < 0 || extents->bounded.y + ty < 0)
+ if (extents->bounded.x + tx < limit.x || extents->bounded.y + ty < limit.y)
return CAIRO_INT_STATUS_UNSUPPORTED;
- _cairo_surface_get_extents (pattern->surface, &limit);
- if (extents->bounded.x + extents->bounded.width + tx > limit.width ||
- extents->bounded.y + extents->bounded.height + ty > limit.height)
+ if (extents->bounded.x + extents->bounded.width + tx > limit.x + limit.width ||
+ extents->bounded.y + extents->bounded.height + ty > limit.y + limit.height)
return CAIRO_INT_STATUS_UNSUPPORTED;
- if (pattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE)
+ tx += limit.x;
+ ty += limit.y;
+
+ if (src->type == CAIRO_SURFACE_TYPE_IMAGE)
status = compositor->draw_image_boxes (dst,
(cairo_image_surface_t *)src,
boxes, tx, ty);
diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c
index 51171faba..3b83d0f29 100644
--- a/src/cairo-os2-surface.c
+++ b/src/cairo-os2-surface.c
@@ -1394,6 +1394,7 @@ static const cairo_surface_backend_t cairo_os2_surface_backend = {
_cairo_os2_surface_map_to_image,
_cairo_os2_surface_unmap_image,
+ _cairo_surface_default_source,
_cairo_os2_surface_acquire_source_image,
_cairo_os2_surface_release_source_image,
NULL, /* snapshot */
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index e872e395d..957cf7bd5 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -242,6 +242,14 @@ _cairo_paginated_surface_create_image_surface (void *abstract_surface,
return image;
}
+static cairo_surface_t *
+_cairo_paginated_surface_source (void *abstract_surface,
+ cairo_rectangle_int_t *extents)
+{
+ cairo_paginated_surface_t *surface = abstract_surface;
+ return _cairo_surface_get_source (surface->target, extents);
+}
+
static cairo_status_t
_cairo_paginated_surface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -682,6 +690,7 @@ static const cairo_surface_backend_t cairo_paginated_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_paginated_surface_source,
_cairo_paginated_surface_acquire_source_image,
_cairo_paginated_surface_release_source_image,
_cairo_paginated_surface_snapshot,
diff --git a/src/cairo-pattern-private.h b/src/cairo-pattern-private.h
index 9b2f875e8..761fce3b9 100644
--- a/src/cairo-pattern-private.h
+++ b/src/cairo-pattern-private.h
@@ -39,6 +39,7 @@
#include "cairo-error-private.h"
#include "cairo-types-private.h"
#include "cairo-list-private.h"
+#include "cairo-surface-private.h"
#include <stdio.h> /* FILE* */
@@ -370,6 +371,13 @@ _cairo_raster_source_pattern_finish (cairo_pattern_t *abstract_pattern);
cairo_private void
_cairo_debug_print_pattern (FILE *file, const cairo_pattern_t *pattern);
+static inline cairo_surface_t *
+_cairo_pattern_get_source (const cairo_surface_pattern_t *pattern,
+ cairo_rectangle_int_t *extents)
+{
+ return _cairo_surface_get_source (pattern->surface, extents);
+}
+
CAIRO_END_DECLS
#endif /* CAIRO_PATTERN_PRIVATE */
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index cf8aab446..dff5a3ae1 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -7274,6 +7274,7 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_default_source,
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* snapshot */
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 8c861cbf8..07155e707 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -4538,6 +4538,7 @@ static const cairo_surface_backend_t cairo_ps_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_default_source,
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* snapshot */
diff --git a/src/cairo-qt-surface.cpp b/src/cairo-qt-surface.cpp
index aaed90cbc..467a3892c 100644
--- a/src/cairo-qt-surface.cpp
+++ b/src/cairo-qt-surface.cpp
@@ -1561,6 +1561,7 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_default_source,
_cairo_qt_surface_acquire_source_image,
_cairo_qt_surface_release_source_image,
_cairo_qt_surface_acquire_dest_image,
diff --git a/src/cairo-quartz-image-surface.c b/src/cairo-quartz-image-surface.c
index b5f861252..19cd4245e 100644
--- a/src/cairo-quartz-image-surface.c
+++ b/src/cairo-quartz-image-surface.c
@@ -260,6 +260,7 @@ static const cairo_surface_backend_t cairo_quartz_image_surface_backend = {
_cairo_quartz_image_surface_map_to_image,
_cairo_quartz_image_surface_unmap_image,
+ _cairo_surface_default_source,
_cairo_quartz_image_surface_acquire_source_image,
NULL, /* release_source_image */
NULL, /* snapshot */
diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index 5316a1043..3b626cc0c 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -535,6 +535,7 @@ static const cairo_surface_backend_t proxy_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_default_source,
proxy_acquire_source_image,
proxy_release_source_image,
};
@@ -1135,6 +1136,7 @@ static const cairo_surface_backend_t cairo_recording_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_default_source,
_cairo_recording_surface_acquire_source_image,
_cairo_recording_surface_release_source_image,
_cairo_recording_surface_snapshot,
diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c
index 8851a9ec1..a779780dd 100644
--- a/src/cairo-script-surface.c
+++ b/src/cairo-script-surface.c
@@ -2090,6 +2090,19 @@ _device_destroy (void *abstract_device)
free (ctx);
}
+static cairo_surface_t *
+_cairo_script_surface_source (void *abstract_surface,
+ cairo_rectangle_int_t *extents)
+{
+ cairo_script_surface_t *surface = abstract_surface;
+
+ extents->x = extents->y = 0;
+ extents->width = surface->width;
+ extents->height = surface->height;
+
+ return &surface->base;
+}
+
static cairo_status_t
_cairo_script_surface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -3557,6 +3570,7 @@ _cairo_script_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_script_surface_source,
_cairo_script_surface_acquire_source_image,
_cairo_script_surface_release_source_image,
_cairo_script_surface_snapshot,
diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index 0e94be86a..0abb505e9 100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -379,18 +379,12 @@ error:
}
static cairo_surface_t *
-unwrap_surface (const cairo_pattern_t *pattern)
+unwrap_source (const cairo_pattern_t *pattern)
{
- cairo_surface_t *surface;
+ cairo_rectangle_int_t limit;
- surface = ((const cairo_surface_pattern_t *) pattern)->surface;
- if (_cairo_surface_is_paginated (surface))
- surface = _cairo_paginated_surface_get_recording (surface);
- if (_cairo_surface_is_snapshot (surface))
- surface = _cairo_surface_snapshot_get_target (surface);
- if (_cairo_surface_is_observer (surface))
- surface = _cairo_surface_observer_get_target (surface);
- return surface;
+ return _cairo_pattern_get_source ((cairo_surface_pattern_t *)pattern,
+ &limit);
}
static cairo_bool_t
@@ -417,7 +411,7 @@ recording_pattern_contains_sample (const cairo_pattern_t *pattern,
if (pattern->extend == CAIRO_EXTEND_NONE)
return TRUE;
- surface = (cairo_recording_surface_t *) unwrap_surface (pattern);
+ surface = (cairo_recording_surface_t *) unwrap_source (pattern);
if (surface->unbounded)
return TRUE;
@@ -482,7 +476,7 @@ composite_aligned_boxes (const cairo_spans_compositor_t *compositor,
boxes);
recording_clip = _cairo_clip_from_boxes (boxes);
- status = _cairo_recording_surface_replay_with_clip (unwrap_surface (source),
+ status = _cairo_recording_surface_replay_with_clip (unwrap_source (source),
&source->matrix,
dst, recording_clip);
_cairo_clip_destroy (recording_clip);
diff --git a/src/cairo-surface-backend-private.h b/src/cairo-surface-backend-private.h
index 1f076e226..f7bfbd7b1 100644
--- a/src/cairo-surface-backend-private.h
+++ b/src/cairo-surface-backend-private.h
@@ -70,6 +70,10 @@ struct _cairo_surface_backend {
(*unmap_image) (void *surface,
cairo_image_surface_t *image);
+ cairo_surface_t *
+ (*source) (void *abstract_surface,
+ cairo_rectangle_int_t *extents);
+
cairo_warn cairo_status_t
(*acquire_source_image) (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -197,6 +201,10 @@ struct _cairo_surface_backend {
(*get_supported_mime_types) (void *surface);
};
+cairo_private cairo_surface_t *
+_cairo_surface_default_source (void *surface,
+ cairo_rectangle_int_t *extents);
+
CAIRO_END_DECLS
#endif /* CAIRO_SURFACE_BACKEND_PRIVATE_H */
diff --git a/src/cairo-surface-observer.c b/src/cairo-surface-observer.c
index c70c0cc04..e5d33714d 100644
--- a/src/cairo-surface-observer.c
+++ b/src/cairo-surface-observer.c
@@ -1276,6 +1276,14 @@ _cairo_surface_observer_get_font_options (void *abstract_surface,
surface->target->backend->get_font_options (surface->target, options);
}
+static cairo_surface_t *
+_cairo_surface_observer_source (void *abstract_surface,
+ cairo_rectangle_int_t *extents)
+{
+ cairo_surface_observer_t *surface = abstract_surface;
+ return _cairo_surface_get_source (surface->target, extents);
+}
+
static cairo_status_t
_cairo_surface_observer_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -1339,6 +1347,7 @@ static const cairo_surface_backend_t _cairo_surface_observer_backend = {
_cairo_surface_observer_map_to_image,
_cairo_surface_observer_unmap_image,
+ _cairo_surface_observer_source,
_cairo_surface_observer_acquire_source_image,
_cairo_surface_observer_release_source_image,
_cairo_surface_observer_snapshot,
diff --git a/src/cairo-surface-private.h b/src/cairo-surface-private.h
index 5a664803e..af24e250a 100644
--- a/src/cairo-surface-private.h
+++ b/src/cairo-surface-private.h
@@ -105,4 +105,8 @@ struct _cairo_surface {
cairo_private cairo_surface_t *
_cairo_int_surface_create_in_error (cairo_int_status_t status);
+cairo_private cairo_surface_t *
+_cairo_surface_get_source (cairo_surface_t *surface,
+ cairo_rectangle_int_t *extents);
+
#endif /* CAIRO_SURFACE_PRIVATE_H */
diff --git a/src/cairo-surface-snapshot.c b/src/cairo-surface-snapshot.c
index 4bc40e7eb..69523744c 100644
--- a/src/cairo-surface-snapshot.c
+++ b/src/cairo-surface-snapshot.c
@@ -68,6 +68,14 @@ _cairo_surface_snapshot_flush (void *abstract_surface)
return surface->target->status;
}
+static cairo_surface_t *
+_cairo_surface_snapshot_source (void *abstract_surface,
+ cairo_rectangle_int_t *extents)
+{
+ cairo_surface_snapshot_t *surface = abstract_surface;
+ return _cairo_surface_get_source (surface->target, extents);
+}
+
static cairo_status_t
_cairo_surface_snapshot_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -107,6 +115,7 @@ static const cairo_surface_backend_t _cairo_surface_snapshot_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_snapshot_source,
_cairo_surface_snapshot_acquire_source_image,
_cairo_surface_snapshot_release_source_image,
NULL, /* snapshot */
diff --git a/src/cairo-surface-subsurface.c b/src/cairo-surface-subsurface.c
index b2f7e0a10..4d80cfd70 100644
--- a/src/cairo-surface-subsurface.c
+++ b/src/cairo-surface-subsurface.c
@@ -293,6 +293,19 @@ _cairo_surface_subsurface_get_font_options (void *abstract_surface,
surface->target->backend->get_font_options (surface->target, options);
}
+static cairo_surface_t *
+_cairo_surface_subsurface_source (void *abstract_surface,
+ cairo_rectangle_int_t *extents)
+{
+ cairo_surface_subsurface_t *surface = abstract_surface;
+ cairo_surface_t *source;
+
+ source = _cairo_surface_get_source (surface->target, extents);
+ *extents = surface->extents;
+
+ return source;
+}
+
static cairo_status_t
_cairo_surface_subsurface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -386,6 +399,7 @@ static const cairo_surface_backend_t _cairo_surface_subsurface_backend = {
_cairo_surface_subsurface_map_to_image,
_cairo_surface_subsurface_unmap_image,
+ _cairo_surface_subsurface_source,
_cairo_surface_subsurface_acquire_source_image,
_cairo_surface_subsurface_release_source_image,
_cairo_surface_subsurface_snapshot,
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 99a0777e9..9a4b88d0c 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1714,6 +1714,22 @@ _cairo_surface_release_source_image (cairo_surface_t *surface,
surface->backend->release_source_image (surface, image, image_extra);
}
+cairo_surface_t *
+_cairo_surface_get_source (cairo_surface_t *surface,
+ cairo_rectangle_int_t *extents)
+{
+ assert (surface->backend->source);
+ return surface->backend->source (surface, extents);
+}
+
+cairo_surface_t *
+_cairo_surface_default_source (void *surface,
+ cairo_rectangle_int_t *extents)
+{
+ _cairo_surface_get_extents(surface, extents);
+ return surface;
+}
+
static cairo_status_t
_pattern_has_error (const cairo_pattern_t *pattern)
{
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index c5a02c239..7f87c934a 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -2603,6 +2603,7 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_default_source,
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* snapshot */
diff --git a/src/cairo-tee-surface.c b/src/cairo-tee-surface.c
index 4930a0bb7..d26ea9e60 100644
--- a/src/cairo-tee-surface.c
+++ b/src/cairo-tee-surface.c
@@ -119,6 +119,14 @@ _cairo_tee_surface_finish (void *abstract_surface)
return CAIRO_STATUS_SUCCESS;
}
+static cairo_surface_t *
+_cairo_tee_surface_source (void *abstract_surface,
+ cairo_rectangle_int_t *extents)
+{
+ cairo_tee_surface_t *surface = abstract_surface;
+ return _cairo_surface_get_source (surface->master.target, extents);
+}
+
static cairo_status_t
_cairo_tee_surface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -389,6 +397,7 @@ static const cairo_surface_backend_t cairo_tee_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_tee_surface_source,
_cairo_tee_surface_acquire_source_image,
_cairo_tee_surface_release_source_image,
_cairo_tee_surface_snapshot,
diff --git a/src/cairo-traps-compositor.c b/src/cairo-traps-compositor.c
index ac0a56f50..4c05e807f 100644
--- a/src/cairo-traps-compositor.c
+++ b/src/cairo-traps-compositor.c
@@ -1102,39 +1102,31 @@ upload_boxes (const cairo_traps_compositor_t *compositor,
{
cairo_surface_t *dst = extents->surface;
const cairo_pattern_t *source = &extents->source_pattern.base;
- const cairo_surface_pattern_t *pattern;
cairo_surface_t *src;
cairo_rectangle_int_t limit;
cairo_int_status_t status;
int tx, ty;
- pattern = (const cairo_surface_pattern_t *) source;
- src = pattern->surface;
+ src = _cairo_pattern_get_source((cairo_surface_pattern_t *)source,
+ &limit);
if (!(src->type == CAIRO_SURFACE_TYPE_IMAGE || src->type == dst->type))
return CAIRO_INT_STATUS_UNSUPPORTED;
if (! _cairo_matrix_is_integer_translation (&source->matrix, &tx, &ty))
return CAIRO_INT_STATUS_UNSUPPORTED;
- if (_cairo_surface_is_snapshot (src))
- src = _cairo_surface_snapshot_get_target (src);
- if (_cairo_surface_is_observer (src))
- src = _cairo_surface_observer_get_target (src);
- if (_cairo_surface_is_subsurface (src)) {
- _cairo_surface_subsurface_offset (src, &tx, &ty);
- src = _cairo_surface_subsurface_get_target (src);
- }
-
/* Check that the data is entirely within the image */
- if (extents->bounded.x + tx < 0 || extents->bounded.y + ty < 0)
+ if (extents->bounded.x + tx < limit.x || extents->bounded.y + ty < limit.y)
return CAIRO_INT_STATUS_UNSUPPORTED;
- _cairo_surface_get_extents (pattern->surface, &limit);
- if (extents->bounded.x + extents->bounded.width + tx > limit.width ||
- extents->bounded.y + extents->bounded.height + ty > limit.height)
+ if (extents->bounded.x + extents->bounded.width + tx > limit.x + limit.width ||
+ extents->bounded.y + extents->bounded.height + ty > limit.y + limit.height)
return CAIRO_INT_STATUS_UNSUPPORTED;
- if (pattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE)
+ tx += limit.x;
+ ty += limit.y;
+
+ if (src->type == CAIRO_SURFACE_TYPE_IMAGE)
status = compositor->draw_image_boxes (dst,
(cairo_image_surface_t *)src,
boxes, tx, ty);
diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c
index ee2d0e346..5bb6bfc44 100644
--- a/src/cairo-type3-glyph-surface.c
+++ b/src/cairo-type3-glyph-surface.c
@@ -331,6 +331,7 @@ static const cairo_surface_backend_t cairo_type3_glyph_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ NULL, /* source */
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* snapshot */
diff --git a/src/cairo-vg-surface.c b/src/cairo-vg-surface.c
index e285d6b61..afbf7a036 100644
--- a/src/cairo-vg-surface.c
+++ b/src/cairo-vg-surface.c
@@ -1487,6 +1487,7 @@ static const cairo_surface_backend_t cairo_vg_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_default_source,
_vg_surface_acquire_source_image,
_vg_surface_release_source_image,
NULL, /* snapshot */
diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c
index 931ae0f57..17a68f787 100644
--- a/src/cairo-win32-printing-surface.c
+++ b/src/cairo-win32-printing-surface.c
@@ -1881,6 +1881,7 @@ static const cairo_surface_backend_t cairo_win32_printing_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_default_source,
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* snapshot */
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index c7d3216c8..244abc022 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -1937,6 +1937,7 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
_cairo_win32_surface_map_to_image,
_cairo_win32_surface_unmap_image,
+ _cairo_surface_default_source,
_cairo_win32_surface_acquire_source_image,
_cairo_win32_surface_release_source_image,
NULL, /* snapshot */
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index aa2bbbff5..9e2c665af 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -457,6 +457,19 @@ FAIL:
return _cairo_surface_create_in_error (status);
}
+static cairo_surface_t *
+_cairo_xcb_surface_source (void *abstract_surface,
+ cairo_rectangle_int_t *extents)
+{
+ cairo_xcb_surface_t *surface = abstract_surface;
+
+ extents->x = extents->y = 0;
+ extents->width = surface->width;
+ extents->height = surface->height;
+
+ return &surface->base;
+}
+
static cairo_status_t
_cairo_xcb_surface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -1052,6 +1065,7 @@ const cairo_surface_backend_t _cairo_xcb_surface_backend = {
_cairo_xcb_surface_map_to_image,
_cairo_xcb_surface_unmap,
+ _cairo_xcb_surface_source,
_cairo_xcb_surface_acquire_source_image,
_cairo_xcb_surface_release_source_image,
NULL, /* snapshot */
diff --git a/src/cairo-xlib-source.c b/src/cairo-xlib-source.c
index a098cf2c8..549879469 100644
--- a/src/cairo-xlib-source.c
+++ b/src/cairo-xlib-source.c
@@ -59,17 +59,10 @@
#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */
static cairo_xlib_surface_t *
-unwrap_surface (cairo_surface_t *surface)
+unwrap_source (const cairo_surface_pattern_t *pattern)
{
- if (_cairo_surface_is_paginated (surface))
- surface = _cairo_paginated_surface_get_recording (surface);
- if (_cairo_surface_is_snapshot (surface))
- surface = _cairo_surface_snapshot_get_target (surface);
- if (_cairo_surface_is_subsurface (surface))
- surface = _cairo_surface_subsurface_get_target (surface);
- if (_cairo_surface_is_observer (surface))
- surface = _cairo_surface_observer_get_target (surface);
- return (cairo_xlib_surface_t *)surface;
+ cairo_rectangle_int_t limits;
+ return (cairo_xlib_surface_t *)_cairo_pattern_get_source (pattern, &limits);
}
static cairo_status_t
@@ -760,7 +753,7 @@ native_source (cairo_xlib_surface_t *dst,
extents, sample,
src_x, src_y);
- src = unwrap_surface (pattern->surface);
+ src = unwrap_source (pattern);
if (pattern->base.filter == CAIRO_FILTER_NEAREST &&
sample->x >= 0 && sample->y >= 0 &&
@@ -1037,7 +1030,7 @@ _cairo_xlib_source_create_for_pattern (cairo_surface_t *_dst,
cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t *)pattern;
if (spattern->surface->type == CAIRO_SURFACE_TYPE_XLIB &&
_cairo_xlib_surface_same_screen (dst,
- unwrap_surface (spattern->surface)))
+ unwrap_source (spattern)))
return native_source (dst, spattern, is_mask,
extents, sample,
src_x, src_y);
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 5fb9185c3..71ddafb96 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1224,6 +1224,19 @@ _cairo_xlib_surface_draw_image (cairo_xlib_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
+static cairo_surface_t *
+_cairo_xlib_surface_source(void *abstract_surface,
+ cairo_rectangle_int_t *extents)
+{
+ cairo_xlib_surface_t *surface = abstract_surface;
+
+ extents->x = extents->y = 0;
+ extents->width = surface->width;
+ extents->height = surface->height;
+
+ return &surface->base;
+}
+
static cairo_status_t
_cairo_xlib_surface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -1400,6 +1413,7 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = {
_cairo_xlib_surface_map_to_image,
_cairo_xlib_surface_unmap_image,
+ _cairo_xlib_surface_source,
_cairo_xlib_surface_acquire_source_image,
_cairo_xlib_surface_release_source_image,
_cairo_xlib_surface_snapshot,
diff --git a/src/cairo-xlib-xcb-surface.c b/src/cairo-xlib-xcb-surface.c
index 5021cfcc0..2002fc340 100644
--- a/src/cairo-xlib-xcb-surface.c
+++ b/src/cairo-xlib-xcb-surface.c
@@ -137,6 +137,14 @@ _cairo_xlib_xcb_surface_unmap (void *abstract_surface,
return cairo_surface_status (&surface->xcb->base);
}
+static cairo_surface_t *
+_cairo_xlib_xcb_surface_source (void *abstract_surface,
+ cairo_rectangle_int_t *extents)
+{
+ cairo_xlib_xcb_surface_t *surface = abstract_surface;
+ return _cairo_surface_get_source (&surface->cb->base, extents);
+}
+
static cairo_status_t
_cairo_xlib_xcb_surface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
@@ -275,6 +283,7 @@ static const cairo_surface_backend_t _cairo_xlib_xcb_surface_backend = {
_cairo_xlib_xcb_surface_map_to_image,
_cairo_xlib_xcb_surface_unmap,
+ _cairo_xlib_xcb_surface_source,
_cairo_xlib_xcb_surface_acquire_source_image,
_cairo_xlib_xcb_surface_release_source_image,
NULL, /* snapshot */
diff --git a/src/cairo-xml-surface.c b/src/cairo-xml-surface.c
index dd9d3f6f9..a2e6a9f1f 100644
--- a/src/cairo-xml-surface.c
+++ b/src/cairo-xml-surface.c
@@ -1002,6 +1002,7 @@ _cairo_xml_surface_backend = {
NULL, /* map_to_image */
NULL, /* unmap_image */
+ _cairo_surface_default_source,
NULL, /* acquire source image */
NULL, /* release source image */
NULL, /* snapshot */
diff --git a/src/drm/cairo-drm-gallium-surface.c b/src/drm/cairo-drm-gallium-surface.c
index b48975302..aa3f45ebe 100644
--- a/src/drm/cairo-drm-gallium-surface.c
+++ b/src/drm/cairo-drm-gallium-surface.c
@@ -468,6 +468,7 @@ static const cairo_surface_backend_t gallium_surface_backend = {
gallium_surface_create_similar,
gallium_surface_finish,
+ NULL,
gallium_surface_acquire_source_image,
gallium_surface_release_source_image,
diff --git a/src/drm/cairo-drm-i915-surface.c b/src/drm/cairo-drm-i915-surface.c
index 2a55889fe..020012120 100644
--- a/src/drm/cairo-drm-i915-surface.c
+++ b/src/drm/cairo-drm-i915-surface.c
@@ -2343,6 +2343,8 @@ static const cairo_surface_backend_t i915_surface_backend = {
i915_surface_create_similar,
i915_surface_finish,
+
+ NULL,
intel_surface_acquire_source_image,
intel_surface_release_source_image,
diff --git a/src/drm/cairo-drm-i965-surface.c b/src/drm/cairo-drm-i965-surface.c
index 71061a0e9..0891c954d 100644
--- a/src/drm/cairo-drm-i965-surface.c
+++ b/src/drm/cairo-drm-i965-surface.c
@@ -1495,6 +1495,8 @@ static const cairo_surface_backend_t i965_surface_backend = {
i965_surface_create_similar,
i965_surface_finish,
+
+ NULL,
intel_surface_acquire_source_image,
intel_surface_release_source_image,
diff --git a/src/drm/cairo-drm-intel-surface.c b/src/drm/cairo-drm-intel-surface.c
index f28c75003..fe9875933 100644
--- a/src/drm/cairo-drm-intel-surface.c
+++ b/src/drm/cairo-drm-intel-surface.c
@@ -253,8 +253,11 @@ static const cairo_surface_backend_t intel_surface_backend = {
intel_surface_create_similar,
intel_surface_finish,
+
+ NULL,
intel_surface_acquire_source_image,
intel_surface_release_source_image,
+
NULL, NULL, NULL,
NULL, /* composite */
NULL, /* fill */
diff --git a/src/drm/cairo-drm-radeon-surface.c b/src/drm/cairo-drm-radeon-surface.c
index 9335d7b72..9f46ca158 100644
--- a/src/drm/cairo-drm-radeon-surface.c
+++ b/src/drm/cairo-drm-radeon-surface.c
@@ -257,8 +257,11 @@ static const cairo_surface_backend_t radeon_surface_backend = {
radeon_surface_create_similar,
radeon_surface_finish,
+
+ NULL,
radeon_surface_acquire_source_image,
radeon_surface_release_source_image,
+
NULL, NULL, NULL,
NULL, /* composite */
NULL, /* fill */
diff --git a/src/test-compositor-surface.c b/src/test-compositor-surface.c
index 356c16c6b..ddee06f3e 100644
--- a/src/test-compositor-surface.c
+++ b/src/test-compositor-surface.c
@@ -195,6 +195,7 @@ static const cairo_surface_backend_t test_compositor_surface_backend = {
_cairo_image_surface_map_to_image,
_cairo_image_surface_unmap_image,
+ _cairo_image_surface_source,
_cairo_image_surface_acquire_source_image,
_cairo_image_surface_release_source_image,
_cairo_image_surface_snapshot,
diff --git a/src/test-null-compositor-surface.c b/src/test-null-compositor-surface.c
index e94c8a74f..951615525 100644
--- a/src/test-null-compositor-surface.c
+++ b/src/test-null-compositor-surface.c
@@ -198,6 +198,7 @@ static const cairo_surface_backend_t test_compositor_surface_backend = {
_cairo_image_surface_map_to_image,
_cairo_image_surface_unmap_image,
+ _cairo_image_surface_source,
_cairo_image_surface_acquire_source_image,
_cairo_image_surface_release_source_image,
NULL, /* snapshot */
diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c
index e3c8a917b..0a7c79b37 100644
--- a/src/test-paginated-surface.c
+++ b/src/test-paginated-surface.c
@@ -253,6 +253,7 @@ static const cairo_surface_backend_t test_paginated_surface_backend = {
NULL, /* map to image */
NULL, /* unmap image */
+ _cairo_surface_default_source,
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* snapshot */