diff options
Diffstat (limited to 'src/cairo-analysis-surface.c')
-rw-r--r-- | src/cairo-analysis-surface.c | 112 |
1 files changed, 91 insertions, 21 deletions
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index 0e7ba8a38..6889be38f 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -263,7 +263,8 @@ static cairo_int_status_t _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface, const cairo_pattern_t *pattern, cairo_rectangle_int_t *extents, - unsigned int *regions_id) + unsigned int *regions_id, + cairo_analysis_source_t source_type) { const cairo_surface_pattern_t *surface_pattern; cairo_analysis_surface_t *tmp; @@ -273,6 +274,7 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface, cairo_int_status_t analysis_status = CAIRO_INT_STATUS_SUCCESS; cairo_bool_t surface_is_unbounded; cairo_bool_t unused; + cairo_bool_t replay_all; assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE); surface_pattern = (const cairo_surface_pattern_t *) pattern; @@ -288,7 +290,7 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface, tmp = (cairo_analysis_surface_t *) _cairo_analysis_surface_create (surface->target, surface->create_region_ids); if (unlikely (tmp->base.status)) { - status =tmp->base.status; + status = tmp->base.status; goto cleanup1; } proxy = attach_proxy (source, &tmp->base); @@ -298,7 +300,6 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface, assert (status == CAIRO_INT_STATUS_SUCCESS); _cairo_analysis_surface_set_ctm (&tmp->base, &p2d); - source = _cairo_surface_get_source (source, NULL); surface_is_unbounded = (pattern->extend == CAIRO_EXTEND_REPEAT || pattern->extend == CAIRO_EXTEND_REFLECT); @@ -307,22 +308,54 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface, status = _cairo_recording_surface_region_array_attach (source, regions_id); if (unlikely (status)) goto cleanup2; + } + + replay_all = FALSE; + if (surface->target->backend->analyze_recording_surface) { + status = surface->target->backend->analyze_recording_surface ( + surface->target, + surface_pattern, + surface->create_region_ids ? *regions_id : 0, + source_type, + TRUE); + if (status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) { + /* Ensure all commands are replayed even if previously + * replayed and assigned to a region.*/ + replay_all = TRUE; + status = CAIRO_INT_STATUS_SUCCESS; + } + if (unlikely (status)) + goto cleanup3; + } + if (surface->create_region_ids) { status = _cairo_recording_surface_replay_and_create_regions (source, *regions_id, &pattern->matrix, &tmp->base, - surface_is_unbounded); + surface_is_unbounded, + replay_all); if (unlikely (status)) - goto cleanup2; + goto cleanup3; } else { - status = _cairo_recording_surface_replay_with_clip (source, - &pattern->matrix, - &tmp->base, - NULL, /* target clip */ - surface_is_unbounded); + status = _cairo_recording_surface_replay_with_transform (source, + &pattern->matrix, + &tmp->base, + surface_is_unbounded, + replay_all); if (unlikely (status)) - goto cleanup2; + goto cleanup3; + } + + if (surface->target->backend->analyze_recording_surface) { + status = surface->target->backend->analyze_recording_surface ( + surface->target, + surface_pattern, + surface->create_region_ids ? *regions_id : 0, + source_type, + FALSE); + if (unlikely (status)) + goto cleanup3; } /* black background or mime data fills entire extents */ @@ -339,7 +372,7 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface, if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) status = CAIRO_INT_STATUS_SUCCESS; if (unlikely (status)) - goto cleanup2; + goto cleanup3; } } @@ -363,6 +396,10 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface, _cairo_box_round_to_rectangle (&tmp->page_bbox, extents); } + cleanup3: + if (surface->create_region_ids && unlikely (status)) { + _cairo_recording_surface_region_array_remove (source, *regions_id); + } cleanup2: detach_proxy (proxy); cleanup1: @@ -454,7 +491,8 @@ _cairo_analysis_surface_paint (void *abstract_surface, backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents, - &surface->source_region_id); + &surface->source_region_id, + CAIRO_ANALYSIS_SOURCE_PAINT); _cairo_rectangle_intersect (&extents, &rec_extents); } @@ -500,7 +538,8 @@ _cairo_analysis_surface_mask (void *abstract_surface, _analyze_recording_surface_pattern (surface, source, &rec_extents, - &surface->source_region_id); + &surface->source_region_id, + CAIRO_ANALYSIS_SOURCE_MASK); if (_cairo_int_status_is_error (backend_source_status)) return backend_source_status; @@ -516,7 +555,8 @@ _cairo_analysis_surface_mask (void *abstract_surface, _analyze_recording_surface_pattern (surface, mask, &rec_extents, - &surface->mask_region_id); + &surface->mask_region_id, + CAIRO_ANALYSIS_MASK_MASK); if (_cairo_int_status_is_error (backend_mask_status)) return backend_mask_status; @@ -578,7 +618,8 @@ _cairo_analysis_surface_stroke (void *abstract_surface, backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents, - &surface->source_region_id); + &surface->source_region_id, + CAIRO_ANALYSIS_SOURCE_STROKE); _cairo_rectangle_intersect (&extents, &rec_extents); } @@ -633,7 +674,8 @@ _cairo_analysis_surface_fill (void *abstract_surface, backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents, - &surface->source_region_id); + &surface->source_region_id, + CAIRO_ANALYSIS_SOURCE_FILL); _cairo_rectangle_intersect (&extents, &rec_extents); } @@ -703,7 +745,8 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface, backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents, - &surface->source_region_id); + &surface->source_region_id, + CAIRO_ANALYSIS_SOURCE_SHOW_GLYPHS); _cairo_rectangle_intersect (&extents, &rec_extents); } @@ -787,7 +830,8 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface, _analyze_recording_surface_pattern (surface, source, &rec_extents, - &surface->source_region_id); + &surface->source_region_id, + CAIRO_ANALYSIS_SOURCE_SHOW_GLYPHS); _cairo_rectangle_intersect (&extents, &rec_extents); } @@ -839,6 +883,25 @@ _cairo_analysis_surface_supports_color_glyph (void *abstract_sur return TRUE; } +static cairo_int_status_t +_cairo_analysis_surface_command_id (void *abstract_surface, + unsigned int recording_id, + unsigned int command_id) +{ + cairo_analysis_surface_t *surface = abstract_surface; + cairo_int_status_t backend_status; + + backend_status = CAIRO_INT_STATUS_SUCCESS; + if (surface->target->backend->command_id != NULL) { + backend_status = + surface->target->backend->command_id (surface->target, + recording_id, + command_id); + } + + return backend_status; +} + static const cairo_surface_backend_t cairo_analysis_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS, @@ -874,7 +937,9 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = { _cairo_analysis_surface_show_text_glyphs, NULL, /* get_supported_mime_types */ _cairo_analysis_surface_tag, - _cairo_analysis_surface_supports_color_glyph + _cairo_analysis_surface_supports_color_glyph, + NULL, /* analyze_recording_surface */ + _cairo_analysis_surface_command_id, }; cairo_surface_t * @@ -1135,7 +1200,12 @@ static const cairo_surface_backend_t cairo_null_surface_backend = { NULL, /* fill_stroke */ _show_glyphs_return_success, /* show_glyphs */ NULL, /* has_show_text_glyphs */ - NULL /* show_text_glyphs */ + NULL, /* show_text_glyphs */ + NULL, /* get_supported_mime_types */ + NULL, /* tag */ + NULL, /* supports_color_glyph */ + NULL, /* analyze_recording_surface */ + NULL, /* command_id*/ }; cairo_surface_t * |