From 638d64a702449fee130b103e623c8fa3b8c06e9b Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Thu, 9 Nov 2017 20:52:36 +1030 Subject: ps: don't acquire image or snapshot in acquire_source_image_from_pattern otherwise emit_surface may not see the mime data --- src/cairo-ps-surface.c | 156 +++++++++++++++++++------------------------------ 1 file changed, 61 insertions(+), 95 deletions(-) (limited to 'src/cairo-ps-surface.c') diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 0e804da3a..7e18f5710 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -1745,7 +1745,6 @@ color_is_gray (double red, double green, double blue) * @source_surface: [out] returns surface of type image surface or recording surface * @x_offset: [out] return x offset of surface * @y_offset: [out] return y offset of surface - * @image_extra: [out] returns image extra for image type surface * * Acquire source surface or raster source pattern. **/ @@ -1758,25 +1757,39 @@ _cairo_ps_surface_acquire_source_surface_from_pattern (cairo_ps_surface_t cairo_rectangle_int_t *src_op_extents, cairo_surface_t **source_surface, double *x_offset, - double *y_offset, - void **image_extra) + double *y_offset) { - cairo_status_t status; - cairo_image_surface_t *image; + cairo_status_t status; + cairo_box_t bbox; *x_offset = 0; *y_offset = 0; - *image_extra = NULL; - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SURFACE: { - cairo_box_t bbox; - cairo_surface_t *surf = ((cairo_surface_pattern_t *) pattern)->surface; + /* get the operation extents in pattern space */ + _cairo_box_from_rectangle (&bbox, extents); + _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &bbox, NULL); + _cairo_box_round_to_rectangle (&bbox, src_op_extents); + + if (pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) { + cairo_surface_t *surf; + + surf = _cairo_raster_source_pattern_acquire (pattern, &surface->base, src_op_extents); + if (!surf) + return CAIRO_INT_STATUS_UNSUPPORTED; + + *src_surface_bounded = _cairo_surface_get_extents (surf, src_surface_extents); + cairo_surface_get_device_offset (surf, x_offset, y_offset); + *source_surface = surf; + } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { + cairo_surface_t *surf; + + *source_surface = ((cairo_surface_pattern_t *) pattern)->surface; + surf = *source_surface; + *src_surface_bounded = _cairo_surface_get_extents (surf, src_surface_extents); if (surf->type == CAIRO_SURFACE_TYPE_RECORDING) { - if (_cairo_surface_is_snapshot (surf)) { + if (_cairo_surface_is_snapshot (surf)) surf = _cairo_surface_snapshot_get_target (surf); - *image_extra = surf; - } + if (surf->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) { cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) surf; @@ -1784,89 +1797,32 @@ _cairo_ps_surface_acquire_source_surface_from_pattern (cairo_ps_surface_t *src_surface_bounded = TRUE; *x_offset = -sub->extents.x; *y_offset = -sub->extents.y; - } else { - *src_surface_bounded = _cairo_surface_get_extents (surf, src_surface_extents); } - *source_surface = surf; - _cairo_box_from_rectangle (&bbox, extents); - _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &bbox, NULL); - _cairo_box_round_to_rectangle (&bbox, src_op_extents); + } else if (surf->type != CAIRO_SURFACE_TYPE_IMAGE) { + cairo_image_surface_t *image; + void *image_extra; - return CAIRO_STATUS_SUCCESS; - } else { - status = _cairo_surface_acquire_source_image (surf, &image, image_extra); - if (unlikely (status)) { - cairo_surface_destroy (*image_extra); + status = _cairo_surface_acquire_source_image (surf, &image, &image_extra); + if (unlikely (status)) return status; - } - } - } break; - - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: { - cairo_surface_t *surf; - cairo_box_t box; - cairo_rectangle_int_t rect; - /* get the operation extents in pattern space */ - _cairo_box_from_rectangle (&box, extents); - _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &box, NULL); - _cairo_box_round_to_rectangle (&box, &rect); - surf = _cairo_raster_source_pattern_acquire (pattern, &surface->base, &rect); - if (!surf) - return CAIRO_INT_STATUS_UNSUPPORTED; - assert (_cairo_surface_is_image (surf)); - image = (cairo_image_surface_t *) surf; - cairo_surface_get_device_offset (surf, x_offset, y_offset); - } break; - - case CAIRO_PATTERN_TYPE_SOLID: - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - default: + *src_surface_bounded = _cairo_surface_get_extents (&image->base, src_surface_extents); + _cairo_surface_release_source_image (surf, image, image_extra); + } + } else { ASSERT_NOT_REACHED; - break; } - src_surface_extents->x = 0; - src_surface_extents->y = 0; - src_surface_extents->width = image->width; - src_surface_extents->height = image->height; - *src_surface_bounded = TRUE; - *source_surface = &image->base; return CAIRO_STATUS_SUCCESS; } static void _cairo_ps_surface_release_source_surface_from_pattern (cairo_ps_surface_t *surface, const cairo_pattern_t *pattern, - cairo_surface_t *source_surface, - void *image_extra) + cairo_surface_t *source_surface) { - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SURFACE: { - cairo_surface_pattern_t *surf_pat = (cairo_surface_pattern_t *) pattern; - if (surf_pat->surface->type == CAIRO_SURFACE_TYPE_RECORDING) { - cairo_surface_destroy (image_extra); - } else { - cairo_image_surface_t *image = (cairo_image_surface_t *) source_surface; - _cairo_surface_release_source_image (surf_pat->surface, image, image_extra); - } - } break; - - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: + if (pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) _cairo_raster_source_pattern_release (pattern, source_surface); - break; - - case CAIRO_PATTERN_TYPE_SOLID: - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - default: - - ASSERT_NOT_REACHED; - break; - } } /** @@ -1946,8 +1902,8 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t cairo_rectangle_int_t src_op_extents; cairo_surface_t *source_surface; double x_offset, y_offset; - void *image_extra; cairo_image_surface_t *image; + void *image_extra; cairo_int_status_t status; cairo_image_transparency_t transparency; @@ -1959,13 +1915,14 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t &src_op_extents, &source_surface, &x_offset, - &y_offset, - &image_extra); + &y_offset); + if (unlikely (status)) + return status; + + status = _cairo_surface_acquire_source_image (source_surface, &image, &image_extra); if (unlikely (status)) return status; - assert (_cairo_surface_is_image (source_surface)); - image = (cairo_image_surface_t *) source_surface; if (image->base.status) return image->base.status; @@ -1992,7 +1949,8 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t ASSERT_NOT_REACHED; } - _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface, image_extra); + _cairo_surface_release_source_image (source_surface, image, image_extra); + _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface); return status; } @@ -3087,6 +3045,10 @@ _cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t *surface, cairo_content_t old_content; cairo_surface_clipper_t old_clipper; cairo_int_status_t status; + cairo_surface_t *free_me = NULL; + + if (_cairo_surface_is_snapshot (recording_surface)) + free_me = recording_surface = _cairo_surface_snapshot_get_target (recording_surface); old_content = surface->content; old_width = surface->width; @@ -3154,6 +3116,7 @@ _cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t *surface, _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, &surface->cairo_to_ps); + cairo_surface_destroy (free_me); return status; } @@ -3234,10 +3197,16 @@ _cairo_ps_surface_emit_surface (cairo_ps_surface_t *surface, status = _cairo_ps_surface_emit_recording_surface (surface, source_surface, src_op_extents, FALSE); } } else { - cairo_image_surface_t *image = (cairo_image_surface_t *) source_surface; + cairo_image_surface_t *image; + void *image_extra; + + status = _cairo_surface_acquire_source_image (source_surface, &image, &image_extra); + if (unlikely (status)) + return status; status = _cairo_ps_surface_emit_image (surface, image, op, source_pattern->filter, stencil_mask); + _cairo_surface_release_source_image (source_surface, image, image_extra); } return status; @@ -3285,7 +3254,6 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface, cairo_rectangle_int_t src_op_extents; cairo_surface_t *source_surface; double x_offset, y_offset; - void *image_extra; cairo_status_t status; cairo_matrix_t cairo_p2d, ps_p2d; cairo_path_fixed_t path; @@ -3303,8 +3271,7 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface, &src_op_extents, &source_surface, &x_offset, - &y_offset, - &image_extra); + &y_offset); if (unlikely (status)) return status; @@ -3406,7 +3373,7 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface, if (image) cairo_surface_destroy (&image->base); - _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface, image_extra); + _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface); return status; } @@ -3442,8 +3409,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface, &bounded, &src_op_extents, &source_surface, - &x_offset, &y_offset, - &image_extra); + &x_offset, &y_offset); if (unlikely (status)) return status; @@ -3648,7 +3614,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface, if (image) cairo_surface_destroy (&image->base); - _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface, image_extra); + _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface); return status; } -- cgit v1.2.1