diff options
author | Adrian Johnson <ajohnson@redneon.com> | 2012-04-08 10:57:23 +0930 |
---|---|---|
committer | Adrian Johnson <ajohnson@redneon.com> | 2013-09-11 21:18:45 +0930 |
commit | 8addb4798c918000eaa6f6dab138e0abb0efa946 (patch) | |
tree | 34d01723b25b03e574ef82fc9067098716b9bb19 | |
parent | 53255625c07d8f24403f0cb1b5a4dbaac142e4da (diff) |
pdf: avoid making groups a transparency group if not required
If the group contains only a combination of clear and opaque alpha and
only OPERATOR_OVER is used in the group and to paint the group, a
transparency group is not required. This allows the pdf viewer to
replay the group in place.
-rw-r--r-- | src/cairo-pdf-surface-private.h | 2 | ||||
-rw-r--r-- | src/cairo-pdf-surface.c | 125 | ||||
-rw-r--r-- | src/cairo-recording-surface-private.h | 8 | ||||
-rw-r--r-- | src/cairo-recording-surface.c | 113 |
4 files changed, 215 insertions, 33 deletions
diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h index d9f65d800..dfeb1aacb 100644 --- a/src/cairo-pdf-surface-private.h +++ b/src/cairo-pdf-surface-private.h @@ -70,6 +70,7 @@ typedef struct _cairo_pdf_source_surface_entry { unsigned int id; unsigned char *unique_id; unsigned long unique_id_length; + cairo_operator_t operator; cairo_bool_t interpolate; cairo_bool_t stencil_mask; cairo_pdf_resource_t surface_res; @@ -92,6 +93,7 @@ typedef struct _cairo_pdf_pattern { cairo_pattern_t *pattern; cairo_pdf_resource_t pattern_res; cairo_pdf_resource_t gstate_res; + cairo_operator_t operator; cairo_bool_t is_shading; } cairo_pdf_pattern_t; diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 6580d5b69..9ff15031d 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1282,6 +1282,7 @@ _get_source_surface_size (cairo_surface_t *source, * @surface: the pdf surface * @source_surface: A #cairo_surface_t to use as the source surface * @source_pattern: A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source + * @op: the operator used to composite this source * @filter: filter type of the source pattern * @stencil_mask: if true, the surface will be written to the PDF as an /ImageMask * @extents: extents of the operation that is using this source @@ -1306,6 +1307,7 @@ static cairo_int_status_t _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface, cairo_surface_t *source_surface, const cairo_pattern_t *source_pattern, + cairo_operator_t op, cairo_filter_t filter, cairo_bool_t stencil_mask, const cairo_rectangle_int_t *extents, @@ -1406,6 +1408,7 @@ release_source: } surface_entry->id = surface_key.id; + surface_entry->operator = op; surface_entry->interpolate = interpolate; surface_entry->stencil_mask = stencil_mask; surface_entry->unique_id_length = unique_id_length; @@ -1466,6 +1469,7 @@ fail1: static cairo_int_status_t _cairo_pdf_surface_add_pdf_pattern_or_shading (cairo_pdf_surface_t *surface, const cairo_pattern_t *pattern, + cairo_operator_t op, const cairo_rectangle_int_t *extents, cairo_bool_t is_shading, cairo_pdf_resource_t *pattern_res, @@ -1475,6 +1479,7 @@ _cairo_pdf_surface_add_pdf_pattern_or_shading (cairo_pdf_surface_t *surface, cairo_int_status_t status; pdf_pattern.is_shading = is_shading; + pdf_pattern.operator = op; /* Solid colors are emitted into the content stream */ if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) { @@ -1550,12 +1555,14 @@ _get_bbox_from_extents (double surface_height, static cairo_int_status_t _cairo_pdf_surface_add_pdf_shading (cairo_pdf_surface_t *surface, const cairo_pattern_t *pattern, + cairo_operator_t op, const cairo_rectangle_int_t *extents, cairo_pdf_resource_t *shading_res, cairo_pdf_resource_t *gstate_res) { return _cairo_pdf_surface_add_pdf_pattern_or_shading (surface, pattern, + op, extents, TRUE, shading_res, @@ -1565,12 +1572,14 @@ _cairo_pdf_surface_add_pdf_shading (cairo_pdf_surface_t *surface, static cairo_int_status_t _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface, const cairo_pattern_t *pattern, + cairo_operator_t op, const cairo_rectangle_int_t *extents, cairo_pdf_resource_t *pattern_res, cairo_pdf_resource_t *gstate_res) { return _cairo_pdf_surface_add_pdf_pattern_or_shading (surface, pattern, + op, extents, FALSE, pattern_res, @@ -1846,7 +1855,8 @@ static cairo_int_status_t _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface, const cairo_box_double_t *bbox, cairo_pdf_resource_t *resource, - cairo_bool_t is_form) + cairo_bool_t is_form, + cairo_bool_t is_group) { cairo_int_status_t status; @@ -1860,25 +1870,41 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface, if (is_form) { assert (bbox != NULL); - status = - _cairo_pdf_surface_open_stream (surface, - resource, - surface->compress_content, - " /Type /XObject\n" - " /Subtype /Form\n" - " /BBox [ %f %f %f %f ]\n" - " /Group <<\n" - " /Type /Group\n" - " /S /Transparency\n" - " /I true\n" - " /CS /DeviceRGB\n" - " >>\n" - " /Resources %d 0 R\n", - bbox->p1.x, - bbox->p1.y, - bbox->p2.x, - bbox->p2.y, - surface->content_resources.id); + if (is_group) { + status = + _cairo_pdf_surface_open_stream (surface, + resource, + surface->compress_content, + " /Type /XObject\n" + " /Subtype /Form\n" + " /BBox [ %f %f %f %f ]\n" + " /Group <<\n" + " /Type /Group\n" + " /S /Transparency\n" + " /I true\n" + " /CS /DeviceRGB\n" + " >>\n" + " /Resources %d 0 R\n", + bbox->p1.x, + bbox->p1.y, + bbox->p2.x, + bbox->p2.y, + surface->content_resources.id); + } else { + status = + _cairo_pdf_surface_open_stream (surface, + resource, + surface->compress_content, + " /Type /XObject\n" + " /Subtype /Form\n" + " /BBox [ %f %f %f %f ]\n" + " /Resources %d 0 R\n", + bbox->p1.x, + bbox->p1.y, + bbox->p2.x, + bbox->p2.y, + surface->content_resources.id); + } } else { status = _cairo_pdf_surface_open_stream (surface, @@ -2079,7 +2105,7 @@ _cairo_pdf_surface_has_fallback_images (void *abstract_surface, bbox.p1.y = 0; bbox.p2.x = surface->width; bbox.p2.y = surface->height; - status = _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, has_fallbacks); + status = _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, has_fallbacks, has_fallbacks); if (unlikely (status)) return status; @@ -2154,6 +2180,7 @@ _cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t *surfa status = _cairo_pdf_surface_add_source_surface (surface, pad_image, NULL, + FALSE, source->filter, FALSE, extents, @@ -2686,6 +2713,8 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface, int width; int height; cairo_bool_t is_subsurface; + cairo_bool_t transparency_group; + cairo_recording_surface_t *recording; assert (pdf_source->type == CAIRO_PATTERN_TYPE_SURFACE); extents = &pdf_source->hash_entry->extents; @@ -2705,6 +2734,9 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface, is_subsurface = TRUE; } + assert (source->type == CAIRO_SURFACE_TYPE_RECORDING); + recording = (cairo_recording_surface_t *) source; + old_width = surface->width; old_height = surface->height; old_paginated_mode = surface->paginated_mode; @@ -2721,7 +2753,16 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface, surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER; _cairo_pdf_group_resources_clear (&surface->resources); _get_bbox_from_extents (height, extents, &bbox); - status = _cairo_pdf_surface_open_content_stream (surface, &bbox, &pdf_source->hash_entry->surface_res, TRUE); + + /* We can optimize away the transparency group allowing the viewer + * to replay the group in place when all operators are OVER and the + * recording contains only opaque and/or clear alpha. + */ + transparency_group = !(pdf_source->hash_entry->operator == CAIRO_OPERATOR_OVER && + _cairo_recording_surface_has_only_bilevel_alpha (recording) && + _cairo_recording_surface_has_only_op_over (recording)); + status = _cairo_pdf_surface_open_content_stream (surface, &bbox, &pdf_source->hash_entry->surface_res, + TRUE, transparency_group); if (unlikely (status)) goto err; @@ -2805,6 +2846,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, status = _cairo_pdf_surface_add_source_surface (surface, NULL, pattern, + pdf_pattern->operator, pattern->filter, FALSE, &pdf_pattern->extents, @@ -3909,6 +3951,7 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern static cairo_int_status_t _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface, + cairo_operator_t op, const cairo_pattern_t *source, const cairo_rectangle_int_t *extents, cairo_bool_t stencil_mask) @@ -3938,6 +3981,7 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface, status = _cairo_pdf_surface_add_source_surface (surface, NULL, source, + op, source->filter, stencil_mask, extents, @@ -3999,6 +4043,7 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface, static cairo_int_status_t _cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t *surface, + cairo_operator_t op, const cairo_pattern_t *source, const cairo_rectangle_int_t *extents) { @@ -4008,7 +4053,7 @@ _cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t *surface, int alpha; status = _cairo_pdf_surface_add_pdf_shading (surface, source, - extents, + op, extents, &shading_res, &gstate_res); if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO)) return CAIRO_INT_STATUS_SUCCESS; @@ -4062,6 +4107,7 @@ _cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t *surface, static cairo_int_status_t _cairo_pdf_surface_paint_pattern (cairo_pdf_surface_t *surface, + cairo_operator_t op, const cairo_pattern_t *source, const cairo_rectangle_int_t *extents, cairo_bool_t mask) @@ -4070,6 +4116,7 @@ _cairo_pdf_surface_paint_pattern (cairo_pdf_surface_t *surface, case CAIRO_PATTERN_TYPE_SURFACE: case CAIRO_PATTERN_TYPE_RASTER_SOURCE: return _cairo_pdf_surface_paint_surface_pattern (surface, + op, source, extents, mask); @@ -4077,6 +4124,7 @@ _cairo_pdf_surface_paint_pattern (cairo_pdf_surface_t *surface, case CAIRO_PATTERN_TYPE_RADIAL: case CAIRO_PATTERN_TYPE_MESH: return _cairo_pdf_surface_paint_gradient (surface, + op, source, extents); @@ -5701,6 +5749,7 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface, if (_can_paint_pattern (group->mask)) { _cairo_output_stream_printf (surface->output, "q\n"); status = _cairo_pdf_surface_paint_pattern (surface, + CAIRO_OPERATOR_OVER, group->mask, &group->extents, FALSE); @@ -5711,7 +5760,9 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface, } else { pattern_res.id = 0; gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, group->mask, NULL, + status = _cairo_pdf_surface_add_pdf_pattern (surface, group->mask, + CAIRO_OPERATOR_OVER, + NULL, &pattern_res, &gstate_res); if (unlikely (status)) return status; @@ -5774,6 +5825,7 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface, if (_can_paint_pattern (group->source)) { _cairo_output_stream_printf (surface->output, "q\n"); status = _cairo_pdf_surface_paint_pattern (surface, + CAIRO_OPERATOR_OVER, group->source, &group->extents, FALSE); @@ -5784,7 +5836,9 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface, } else { pattern_res.id = 0; gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, group->source, NULL, + status = _cairo_pdf_surface_add_pdf_pattern (surface, group->source, + CAIRO_OPERATOR_OVER, + NULL, &pattern_res, &gstate_res); if (unlikely (status)) return status; @@ -6039,7 +6093,7 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface) return status; _cairo_pdf_group_resources_clear (&surface->resources); - status = _cairo_pdf_surface_open_content_stream (surface, NULL, NULL, FALSE); + status = _cairo_pdf_surface_open_content_stream (surface, NULL, NULL, FALSE, FALSE); if (unlikely (status)) return status; @@ -6327,12 +6381,13 @@ _cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface) bbox.p1.y = 0; bbox.p2.x = surface->width; bbox.p2.y = surface->height; - return _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, TRUE); + return _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, TRUE, TRUE); } /* A PDF stencil mask is an A1 mask used with the current color */ static cairo_int_status_t _cairo_pdf_surface_emit_stencil_mask (cairo_pdf_surface_t *surface, + cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, const cairo_rectangle_int_t *extents) @@ -6379,7 +6434,7 @@ _cairo_pdf_surface_emit_stencil_mask (cairo_pdf_surface_t *surface, return status; _cairo_output_stream_printf (surface->output, "q\n"); - status = _cairo_pdf_surface_paint_surface_pattern (surface, mask, extents, TRUE); + status = _cairo_pdf_surface_paint_surface_pattern (surface, op, mask, extents, TRUE); if (unlikely (status)) return status; @@ -6455,6 +6510,7 @@ _cairo_pdf_surface_paint (void *abstract_surface, if (_can_paint_pattern (source)) { _cairo_output_stream_printf (surface->output, "q\n"); status = _cairo_pdf_surface_paint_pattern (surface, + op, source, &extents.bounded, FALSE); @@ -6468,7 +6524,7 @@ _cairo_pdf_surface_paint (void *abstract_surface, pattern_res.id = 0; gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, + status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op, &extents.bounded, &pattern_res, &gstate_res); if (unlikely (status)) @@ -6609,7 +6665,7 @@ _cairo_pdf_surface_mask (void *abstract_surface, goto cleanup; /* Check if we can use a stencil mask */ - status = _cairo_pdf_surface_emit_stencil_mask (surface, source, mask, &extents.bounded); + status = _cairo_pdf_surface_emit_stencil_mask (surface, op, source, mask, &extents.bounded); if (status != CAIRO_INT_STATUS_UNSUPPORTED) goto cleanup; @@ -6726,7 +6782,7 @@ _cairo_pdf_surface_stroke (void *abstract_surface, pattern_res.id = 0; gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, + status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op, &extents.bounded, &pattern_res, &gstate_res); if (unlikely (status)) @@ -6879,6 +6935,7 @@ _cairo_pdf_surface_fill (void *abstract_surface, goto cleanup; status = _cairo_pdf_surface_paint_pattern (surface, + op, source, &extents.bounded, FALSE); @@ -6892,7 +6949,7 @@ _cairo_pdf_surface_fill (void *abstract_surface, pattern_res.id = 0; gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, + status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op, &extents.bounded, &pattern_res, &gstate_res); if (unlikely (status)) @@ -7067,6 +7124,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface, fill_pattern_res.id = 0; gstate_res.id = 0; status = _cairo_pdf_surface_add_pdf_pattern (surface, fill_source, + fill_op, &extents.bounded, &fill_pattern_res, &gstate_res); @@ -7079,6 +7137,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface, gstate_res.id = 0; status = _cairo_pdf_surface_add_pdf_pattern (surface, stroke_source, + stroke_op, &extents.bounded, &stroke_pattern_res, &gstate_res); @@ -7170,7 +7229,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface, pattern_res.id = 0; gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, + status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op, &extents.bounded, &pattern_res, &gstate_res); if (unlikely (status)) diff --git a/src/cairo-recording-surface-private.h b/src/cairo-recording-surface-private.h index 49194812d..456c63389 100644 --- a/src/cairo-recording-surface-private.h +++ b/src/cairo-recording-surface-private.h @@ -136,6 +136,8 @@ typedef struct _cairo_recording_surface { unsigned int *indices; unsigned int num_indices; cairo_bool_t optimize_clears; + cairo_bool_t has_bilevel_alpha; + cairo_bool_t has_only_op_over; struct bbtree { cairo_box_t extents; @@ -184,4 +186,10 @@ _cairo_recording_surface_get_ink_bbox (cairo_recording_surface_t *surface, cairo_box_t *bbox, const cairo_matrix_t *transform); +cairo_private cairo_bool_t +_cairo_recording_surface_has_only_bilevel_alpha (cairo_recording_surface_t *surface); + +cairo_private cairo_bool_t +_cairo_recording_surface_has_only_op_over (cairo_recording_surface_t *surface); + #endif /* CAIRO_RECORDING_SURFACE_H */ diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c index 55a98d023..eb9af464f 100644 --- a/src/cairo-recording-surface.c +++ b/src/cairo-recording-surface.c @@ -87,6 +87,7 @@ #include "cairo-error-private.h" #include "cairo-image-surface-private.h" #include "cairo-recording-surface-inline.h" +#include "cairo-surface-snapshot-inline.h" #include "cairo-surface-wrapper-private.h" #include "cairo-traps-private.h" @@ -420,6 +421,8 @@ cairo_recording_surface_create (cairo_content_t content, surface->indices = NULL; surface->num_indices = 0; surface->optimize_clears = TRUE; + surface->has_bilevel_alpha = FALSE; + surface->has_only_op_over = FALSE; return &surface->base; } @@ -1603,6 +1606,65 @@ _cairo_recording_surface_get_visible_commands (cairo_recording_surface_t *surfac return num_visible; } +static void +_cairo_recording_surface_merge_source_attributes (cairo_recording_surface_t *surface, + cairo_operator_t op, + const cairo_pattern_t *source) +{ + if (op != CAIRO_OPERATOR_OVER) + surface->has_only_op_over = FALSE; + + if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { + cairo_surface_pattern_t *surf_pat = (cairo_surface_pattern_t *) source; + cairo_surface_t *surf = surf_pat->surface; + cairo_surface_t *free_me; + + if (_cairo_surface_is_snapshot (surf)) + free_me = surf = _cairo_surface_snapshot_get_target (surf); + + if (surf->type == CAIRO_SURFACE_TYPE_RECORDING) { + cairo_recording_surface_t *rec_surf = (cairo_recording_surface_t *) surf; + + if (! _cairo_recording_surface_has_only_bilevel_alpha (rec_surf)) + surface->has_bilevel_alpha = FALSE; + + if (! _cairo_recording_surface_has_only_op_over (rec_surf)) + surface->has_only_op_over = FALSE; + + } else if (surf->type == CAIRO_SURFACE_TYPE_IMAGE) { + cairo_image_surface_t *img_surf = (cairo_image_surface_t *) surf; + + if (_cairo_image_analyze_transparency (img_surf) == CAIRO_IMAGE_HAS_ALPHA) + surface->has_bilevel_alpha = FALSE; + + } + + cairo_surface_destroy (free_me); + return; + + } else if (source->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) { + cairo_surface_t *image; + cairo_surface_t *raster; + + image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); + raster = _cairo_raster_source_pattern_acquire (source, image, NULL); + cairo_surface_destroy (image); + if (raster) { + if (raster->type == CAIRO_SURFACE_TYPE_IMAGE) { + if (_cairo_image_analyze_transparency ((cairo_image_surface_t *)raster) == CAIRO_IMAGE_HAS_ALPHA) + surface->has_bilevel_alpha = FALSE; + } + + _cairo_raster_source_pattern_release (source, raster); + if (raster->type == CAIRO_SURFACE_TYPE_IMAGE) + return; + } + } + + if (!_cairo_pattern_is_clear (source) && !_cairo_pattern_is_opaque (source, NULL)) + surface->has_bilevel_alpha = FALSE; +} + static cairo_status_t _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface, const cairo_rectangle_int_t *surface_extents, @@ -1652,6 +1714,9 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface, if (! _cairo_surface_wrapper_get_target_extents (&wrapper, &extents)) goto done; + surface->has_bilevel_alpha = TRUE; + surface->has_only_op_over = TRUE; + num_elements = surface->commands.num_elements; elements = _cairo_array_index (&surface->commands, 0); if (extents.width < r->width || extents.height < r->height) { @@ -1675,6 +1740,11 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface, command->header.op, &command->paint.source.base, command->header.clip); + if (type == CAIRO_RECORDING_CREATE_REGIONS) { + _cairo_recording_surface_merge_source_attributes (surface, + command->header.op, + &command->paint.source.base); + } break; case CAIRO_COMMAND_MASK: @@ -1683,6 +1753,14 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface, &command->mask.source.base, &command->mask.mask.base, command->header.clip); + if (type == CAIRO_RECORDING_CREATE_REGIONS) { + _cairo_recording_surface_merge_source_attributes (surface, + command->header.op, + &command->mask.source.base); + _cairo_recording_surface_merge_source_attributes (surface, + command->header.op, + &command->mask.mask.base); + } break; case CAIRO_COMMAND_STROKE: @@ -1696,6 +1774,11 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface, command->stroke.tolerance, command->stroke.antialias, command->header.clip); + if (type == CAIRO_RECORDING_CREATE_REGIONS) { + _cairo_recording_surface_merge_source_attributes (surface, + command->header.op, + &command->stroke.source.base); + } break; case CAIRO_COMMAND_FILL: @@ -1737,6 +1820,14 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface, stroke_command->stroke.tolerance, stroke_command->stroke.antialias, command->header.clip); + if (type == CAIRO_RECORDING_CREATE_REGIONS) { + _cairo_recording_surface_merge_source_attributes (surface, + command->header.op, + &command->fill.source.base); + _cairo_recording_surface_merge_source_attributes (surface, + command->header.op, + &command->stroke.source.base); + } i++; } } @@ -1749,6 +1840,11 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface, command->fill.tolerance, command->fill.antialias, command->header.clip); + if (type == CAIRO_RECORDING_CREATE_REGIONS) { + _cairo_recording_surface_merge_source_attributes (surface, + command->header.op, + &command->fill.source.base); + } } break; @@ -1762,6 +1858,11 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface, command->show_text_glyphs.cluster_flags, command->show_text_glyphs.scaled_font, command->header.clip); + if (type == CAIRO_RECORDING_CREATE_REGIONS) { + _cairo_recording_surface_merge_source_attributes (surface, + command->header.op, + &command->show_text_glyphs.source.base); + } break; default: @@ -2070,3 +2171,15 @@ cairo_recording_surface_get_extents (cairo_surface_t *surface, *extents = record->extents_pixels; return TRUE; } + +cairo_bool_t +_cairo_recording_surface_has_only_bilevel_alpha (cairo_recording_surface_t *surface) +{ + return surface->has_bilevel_alpha; +} + +cairo_bool_t +_cairo_recording_surface_has_only_op_over (cairo_recording_surface_t *surface) +{ + return surface->has_only_op_over; +} |