static cairo_status_t _cairo_surface_snapshot_flush (void *abstract_surface, unsigned flags) { cairo_surface_snapshot_t *surface = abstract_surface; cairo_surface_t *target; cairo_status_t status; target = _cairo_surface_snapshot_get_target (&surface->base); status = _cairo_surface_flush (target, flags); cairo_surface_destroy (target); return status; }
static cairo_bool_t _cairo_surface_snapshot_get_extents (void *abstract_surface, cairo_rectangle_int_t *extents) { cairo_surface_snapshot_t *surface = abstract_surface; cairo_surface_t *target; cairo_bool_t bounded; target = _cairo_surface_snapshot_get_target (&surface->base); bounded = _cairo_surface_get_extents (target, extents); cairo_surface_destroy (target); return bounded; }
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); if (_cairo_surface_is_snapshot (source)) source = _cairo_surface_snapshot_get_target (source); if (_cairo_surface_is_subsurface (source)) source = _cairo_surface_subsurface_get_target (source); 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_surface_t * unwrap_surface (const cairo_pattern_t *pattern) { cairo_surface_t *surface; 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; }
static cairo_status_t _cairo_surface_snapshot_acquire_source_image (void *abstract_surface, cairo_image_surface_t **image_out, void **extra_out) { cairo_surface_snapshot_t *surface = abstract_surface; struct snapshot_extra *extra; cairo_status_t status; extra = malloc (sizeof (*extra)); if (unlikely (extra == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); extra->target = _cairo_surface_snapshot_get_target (&surface->base); status = _cairo_surface_acquire_source_image (extra->target, image_out, &extra->extra); if (unlikely (status)) { cairo_surface_destroy (extra->target); free (extra); } *extra_out = extra; return status; }
static cairo_int_status_t _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) { cairo_analysis_surface_t *surface = abstract_surface; cairo_int_status_t backend_status; cairo_rectangle_int_t extents; if (surface->target->backend->mask == NULL) { backend_status = CAIRO_INT_STATUS_UNSUPPORTED; } else { backend_status = surface->target->backend->mask (surface->target, op, source, mask, clip); if (_cairo_int_status_is_error (backend_status)) return backend_status; } 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; if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { cairo_surface_t *src_surface = ((cairo_surface_pattern_t *)source)->surface; if (_cairo_surface_is_snapshot (src_surface)) src_surface = _cairo_surface_snapshot_get_target (src_surface); if (_cairo_surface_is_recording (src_surface)) { backend_source_status = _analyze_recording_surface_pattern (surface, source); if (_cairo_int_status_is_error (backend_source_status)) return backend_source_status; } } if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) { cairo_surface_t *mask_surface = ((cairo_surface_pattern_t *)mask)->surface; if (_cairo_surface_is_snapshot (mask_surface)) mask_surface = _cairo_surface_snapshot_get_target (mask_surface); if (_cairo_surface_is_recording (mask_surface)) { backend_mask_status = _analyze_recording_surface_pattern (surface, mask); if (_cairo_int_status_is_error (backend_mask_status)) return backend_mask_status; } } backend_status = _cairo_analysis_surface_merge_status (backend_source_status, 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_rectangle_intersect (&extents, &mask_extents); } return _add_operation (surface, &extents, backend_status); }