summaryrefslogtreecommitdiff
path: root/src/cairo-analysis-surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo-analysis-surface.c')
-rw-r--r--src/cairo-analysis-surface.c112
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 *