diff options
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 */ |