diff options
Diffstat (limited to 'Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c')
-rw-r--r-- | Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c | 282 |
1 files changed, 192 insertions, 90 deletions
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c index 8516094c200..c4f9a6d3551 100644 --- a/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c +++ b/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c @@ -118,11 +118,11 @@ attach_proxy (cairo_surface_t *source, { struct proxy *proxy; - proxy = malloc (sizeof (*proxy)); + proxy = _cairo_malloc (sizeof (*proxy)); if (unlikely (proxy == NULL)) return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - _cairo_surface_init (&proxy->base, &proxy_backend, NULL, target->content); + _cairo_surface_init (&proxy->base, &proxy_backend, NULL, target->content, target->is_vector); proxy->target = target; _cairo_surface_attach_snapshot (source, &proxy->base, NULL); @@ -138,53 +138,6 @@ detach_proxy (cairo_surface_t *proxy) } static cairo_int_status_t -_analyze_recording_surface_pattern (cairo_analysis_surface_t *surface, - const cairo_pattern_t *pattern) -{ - const cairo_surface_pattern_t *surface_pattern; - cairo_analysis_surface_t *tmp; - cairo_surface_t *source, *proxy; - cairo_matrix_t p2d; - cairo_status_t status, analysis_status; - - assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE); - surface_pattern = (const cairo_surface_pattern_t *) pattern; - assert (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING); - source = surface_pattern->surface; - - proxy = _cairo_surface_has_snapshot (source, &proxy_backend); - if (proxy != NULL) { - /* nothing untoward found so far */ - return CAIRO_STATUS_SUCCESS; - } - - tmp = (cairo_analysis_surface_t *) - _cairo_analysis_surface_create (surface->target); - if (unlikely (tmp->base.status)) - return tmp->base.status; - proxy = attach_proxy (source, &tmp->base); - - p2d = pattern->matrix; - status = cairo_matrix_invert (&p2d); - assert (status == CAIRO_STATUS_SUCCESS); - - cairo_matrix_multiply (&tmp->ctm, &p2d, &surface->ctm); - tmp->has_ctm = ! _cairo_matrix_is_identity (&tmp->ctm); - - source = _cairo_surface_get_source (source, NULL); - status = _cairo_recording_surface_replay_and_create_regions (source, - &tmp->base); - analysis_status = tmp->has_unsupported ? CAIRO_INT_STATUS_IMAGE_FALLBACK : CAIRO_INT_STATUS_SUCCESS; - detach_proxy (proxy); - cairo_surface_destroy (&tmp->base); - - if (unlikely (status)) - return status; - - return analysis_status; -} - -static cairo_int_status_t _add_operation (cairo_analysis_surface_t *surface, cairo_rectangle_int_t *rect, cairo_int_status_t backend_status) @@ -301,6 +254,104 @@ _add_operation (cairo_analysis_surface_t *surface, return status; } +static cairo_int_status_t +_analyze_recording_surface_pattern (cairo_analysis_surface_t *surface, + const cairo_pattern_t *pattern, + cairo_rectangle_int_t *extents) +{ + const cairo_surface_pattern_t *surface_pattern; + cairo_analysis_surface_t *tmp; + cairo_surface_t *source, *proxy; + cairo_matrix_t p2d; + cairo_int_status_t status; + cairo_int_status_t analysis_status = CAIRO_INT_STATUS_SUCCESS; + cairo_bool_t surface_is_unbounded; + cairo_bool_t unused; + + assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE); + surface_pattern = (const cairo_surface_pattern_t *) pattern; + assert (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING); + source = surface_pattern->surface; + + proxy = _cairo_surface_has_snapshot (source, &proxy_backend); + if (proxy != NULL) { + /* nothing untoward found so far */ + return CAIRO_STATUS_SUCCESS; + } + + tmp = (cairo_analysis_surface_t *) + _cairo_analysis_surface_create (surface->target); + if (unlikely (tmp->base.status)) { + status =tmp->base.status; + goto cleanup1; + } + proxy = attach_proxy (source, &tmp->base); + + p2d = pattern->matrix; + status = cairo_matrix_invert (&p2d); + 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); + status = _cairo_recording_surface_replay_and_create_regions (source, + &pattern->matrix, + &tmp->base, + surface_is_unbounded); + if (unlikely (status)) + goto cleanup2; + + /* black background or mime data fills entire extents */ + if (!(source->content & CAIRO_CONTENT_ALPHA) || _cairo_surface_has_mime_image (source)) { + cairo_rectangle_int_t rect; + + if (_cairo_surface_get_extents (source, &rect)) { + cairo_box_t bbox; + + _cairo_box_from_rectangle (&bbox, &rect); + _cairo_matrix_transform_bounding_box_fixed (&p2d, &bbox, NULL); + _cairo_box_round_to_rectangle (&bbox, &rect); + status = _add_operation (tmp, &rect, CAIRO_INT_STATUS_SUCCESS); + if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) + status = CAIRO_INT_STATUS_SUCCESS; + if (unlikely (status)) + goto cleanup2; + } + } + + if (tmp->has_supported) { + surface->has_supported = TRUE; + unused = cairo_region_union (&surface->supported_region, &tmp->supported_region); + } + + if (tmp->has_unsupported) { + surface->has_unsupported = TRUE; + unused = cairo_region_union (&surface->fallback_region, &tmp->fallback_region); + } + + analysis_status = tmp->has_unsupported ? CAIRO_INT_STATUS_IMAGE_FALLBACK : CAIRO_INT_STATUS_SUCCESS; + if (pattern->extend != CAIRO_EXTEND_NONE) { + _cairo_unbounded_rectangle_init (extents); + } else { + status = cairo_matrix_invert (&tmp->ctm); + _cairo_matrix_transform_bounding_box_fixed (&tmp->ctm, + &tmp->page_bbox, NULL); + _cairo_box_round_to_rectangle (&tmp->page_bbox, extents); + } + + cleanup2: + detach_proxy (proxy); + cleanup1: + cairo_surface_destroy (&tmp->base); + + if (unlikely (status)) + return status; + else + return analysis_status; +} + static cairo_status_t _cairo_analysis_surface_finish (void *abstract_surface) { @@ -344,7 +395,7 @@ _cairo_analysis_surface_operation_extents (cairo_analysis_surface_t *surface, if (_cairo_operator_bounded_by_source (op)) { cairo_rectangle_int_t source_extents; - _cairo_pattern_get_extents (source, &source_extents); + _cairo_pattern_get_extents (source, &source_extents, surface->target->is_vector); _cairo_rectangle_intersect (extents, &source_extents); } @@ -355,7 +406,7 @@ static cairo_int_status_t _cairo_analysis_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - const cairo_clip_t *clip) + const cairo_clip_t *clip) { cairo_analysis_surface_t *surface = abstract_surface; cairo_int_status_t backend_status; @@ -371,12 +422,14 @@ _cairo_analysis_surface_paint (void *abstract_surface, return backend_status; } - if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) - backend_status = _analyze_recording_surface_pattern (surface, source); - _cairo_analysis_surface_operation_extents (surface, op, source, clip, &extents); + if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) { + cairo_rectangle_int_t rec_extents; + backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents); + _cairo_rectangle_intersect (&extents, &rec_extents); + } return _add_operation (surface, &extents, backend_status); } @@ -386,7 +439,7 @@ _cairo_analysis_surface_mask (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - const cairo_clip_t *clip) + const cairo_clip_t *clip) { cairo_analysis_surface_t *surface = abstract_surface; cairo_int_status_t backend_status; @@ -402,18 +455,24 @@ _cairo_analysis_surface_mask (void *abstract_surface, return backend_status; } + _cairo_analysis_surface_operation_extents (surface, + op, source, clip, + &extents); if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) { cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS; cairo_int_status_t backend_mask_status = CAIRO_STATUS_SUCCESS; + cairo_rectangle_int_t rec_extents; if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { cairo_surface_t *src_surface = ((cairo_surface_pattern_t *)source)->surface; src_surface = _cairo_surface_get_source (src_surface, NULL); if (_cairo_surface_is_recording (src_surface)) { backend_source_status = - _analyze_recording_surface_pattern (surface, source); + _analyze_recording_surface_pattern (surface, source, &rec_extents); if (_cairo_int_status_is_error (backend_source_status)) return backend_source_status; + + _cairo_rectangle_intersect (&extents, &rec_extents); } } @@ -422,9 +481,11 @@ _cairo_analysis_surface_mask (void *abstract_surface, mask_surface = _cairo_surface_get_source (mask_surface, NULL); if (_cairo_surface_is_recording (mask_surface)) { backend_mask_status = - _analyze_recording_surface_pattern (surface, mask); + _analyze_recording_surface_pattern (surface, mask, &rec_extents); if (_cairo_int_status_is_error (backend_mask_status)) return backend_mask_status; + + _cairo_rectangle_intersect (&extents, &rec_extents); } } @@ -433,14 +494,10 @@ _cairo_analysis_surface_mask (void *abstract_surface, backend_mask_status); } - _cairo_analysis_surface_operation_extents (surface, - op, source, clip, - &extents); - if (_cairo_operator_bounded_by_mask (op)) { cairo_rectangle_int_t mask_extents; - _cairo_pattern_get_extents (mask, &mask_extents); + _cairo_pattern_get_extents (mask, &mask_extents, surface->target->is_vector); _cairo_rectangle_intersect (&extents, &mask_extents); } @@ -448,16 +505,16 @@ _cairo_analysis_surface_mask (void *abstract_surface, } static cairo_int_status_t -_cairo_analysis_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) +_cairo_analysis_surface_stroke (void *abstract_surface, + cairo_operator_t op, + const cairo_pattern_t *source, + const cairo_path_fixed_t *path, + const cairo_stroke_style_t *style, + const cairo_matrix_t *ctm, + const cairo_matrix_t *ctm_inverse, + double tolerance, + cairo_antialias_t antialias, + const cairo_clip_t *clip) { cairo_analysis_surface_t *surface = abstract_surface; cairo_int_status_t backend_status; @@ -476,12 +533,14 @@ _cairo_analysis_surface_stroke (void *abstract_surface, return backend_status; } - if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) - backend_status = _analyze_recording_surface_pattern (surface, source); - _cairo_analysis_surface_operation_extents (surface, op, source, clip, &extents); + if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) { + cairo_rectangle_int_t rec_extents; + backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents); + _cairo_rectangle_intersect (&extents, &rec_extents); + } if (_cairo_operator_bounded_by_mask (op)) { cairo_rectangle_int_t mask_extents; @@ -508,7 +567,7 @@ _cairo_analysis_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - const cairo_clip_t *clip) + const cairo_clip_t *clip) { cairo_analysis_surface_t *surface = abstract_surface; cairo_int_status_t backend_status; @@ -526,12 +585,14 @@ _cairo_analysis_surface_fill (void *abstract_surface, return backend_status; } - if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) - backend_status = _analyze_recording_surface_pattern (surface, source); - _cairo_analysis_surface_operation_extents (surface, op, source, clip, &extents); + if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) { + cairo_rectangle_int_t rec_extents; + backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents); + _cairo_rectangle_intersect (&extents, &rec_extents); + } if (_cairo_operator_bounded_by_mask (op)) { cairo_rectangle_int_t mask_extents; @@ -588,12 +649,14 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface, backend_status = CAIRO_INT_STATUS_UNSUPPORTED; } - if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) - backend_status = _analyze_recording_surface_pattern (surface, source); - _cairo_analysis_surface_operation_extents (surface, op, source, clip, &extents); + if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) { + cairo_rectangle_int_t rec_extents; + backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents); + _cairo_rectangle_intersect (&extents, &rec_extents); + } if (_cairo_operator_bounded_by_mask (op)) { status = _cairo_scaled_font_glyph_device_extents (scaled_font, @@ -664,12 +727,14 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface, return backend_status; } - if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) - backend_status = _analyze_recording_surface_pattern (surface, source); - _cairo_analysis_surface_operation_extents (surface, op, source, clip, &extents); + if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) { + cairo_rectangle_int_t rec_extents; + backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents); + _cairo_rectangle_intersect (&extents, &rec_extents); + } if (_cairo_operator_bounded_by_mask (op)) { status = _cairo_scaled_font_glyph_device_extents (scaled_font, @@ -686,6 +751,39 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface, return _add_operation (surface, &extents, backend_status); } +static cairo_int_status_t +_cairo_analysis_surface_tag (void *abstract_surface, + cairo_bool_t begin, + const char *tag_name, + const char *attributes, + const cairo_pattern_t *source, + const cairo_stroke_style_t *stroke_style, + const cairo_matrix_t *ctm, + const cairo_matrix_t *ctm_inverse, + const cairo_clip_t *clip) +{ + cairo_analysis_surface_t *surface = abstract_surface; + cairo_int_status_t backend_status; + + backend_status = CAIRO_INT_STATUS_SUCCESS; + if (surface->target->backend->tag != NULL) { + backend_status = + surface->target->backend->tag (surface->target, + begin, + tag_name, + attributes, + source, + stroke_style, + ctm, + ctm_inverse, + clip); + if (_cairo_int_status_is_error (backend_status)) + return backend_status; + } + + return backend_status; +} + static const cairo_surface_backend_t cairo_analysis_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS, @@ -718,7 +816,9 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = { NULL, /* fill_stroke */ _cairo_analysis_surface_show_glyphs, _cairo_analysis_surface_has_show_text_glyphs, - _cairo_analysis_surface_show_text_glyphs + _cairo_analysis_surface_show_text_glyphs, + NULL, /* get_supported_mime_types */ + _cairo_analysis_surface_tag }; cairo_surface_t * @@ -731,7 +831,7 @@ _cairo_analysis_surface_create (cairo_surface_t *target) if (unlikely (status)) return _cairo_surface_create_in_error (status); - surface = malloc (sizeof (cairo_analysis_surface_t)); + surface = _cairo_malloc (sizeof (cairo_analysis_surface_t)); if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); @@ -740,7 +840,8 @@ _cairo_analysis_surface_create (cairo_surface_t *target) _cairo_surface_init (&surface->base, &cairo_analysis_surface_backend, NULL, /* device */ - CAIRO_CONTENT_COLOR_ALPHA); + CAIRO_CONTENT_COLOR_ALPHA, + target->is_vector); cairo_matrix_init_identity (&surface->ctm); surface->has_ctm = FALSE; @@ -920,7 +1021,7 @@ _cairo_null_surface_create (cairo_content_t content) { cairo_surface_t *surface; - surface = malloc (sizeof (cairo_surface_t)); + surface = _cairo_malloc (sizeof (cairo_surface_t)); if (unlikely (surface == NULL)) { return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); } @@ -928,7 +1029,8 @@ _cairo_null_surface_create (cairo_content_t content) _cairo_surface_init (surface, &cairo_null_surface_backend, NULL, /* device */ - content); + content, + TRUE); /* is_vector */ return surface; } |