mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-06 09:40:19 +01:00
pdf; Emit subsurface patterns natively.
Encode subsurface patterns into the PDF stream natively (when possible), similar to the cairo-ps backend.
This commit is contained in:
parent
8ded35fd69
commit
5fe7c5842f
1 changed files with 94 additions and 19 deletions
|
|
@ -53,6 +53,7 @@
|
|||
#include "cairo-paginated-private.h"
|
||||
#include "cairo-scaled-font-subsets-private.h"
|
||||
#include "cairo-surface-clipper-private.h"
|
||||
#include "cairo-surface-subsurface-private.h"
|
||||
#include "cairo-type3-glyph-surface-private.h"
|
||||
|
||||
#include <time.h>
|
||||
|
|
@ -1051,18 +1052,26 @@ _get_source_surface_size (cairo_surface_t *source,
|
|||
const unsigned char *mime_data;
|
||||
unsigned int mime_data_length;
|
||||
|
||||
if (_cairo_surface_is_recording (source)) {
|
||||
cairo_recording_surface_t *recording_surface = (cairo_recording_surface_t *) source;
|
||||
cairo_box_t bbox;
|
||||
if (source->type == CAIRO_SURFACE_TYPE_RECORDING) {
|
||||
if (source->backend->type == CAIRO_INTERNAL_SURFACE_TYPE_SUBSURFACE) {
|
||||
cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source;
|
||||
|
||||
status = _cairo_recording_surface_get_bbox (recording_surface, &bbox, NULL);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
*width = sub->extents.width;
|
||||
*height = sub->extents.height;
|
||||
|
||||
_cairo_box_round_to_rectangle (&bbox, &extents);
|
||||
} else {
|
||||
cairo_recording_surface_t *recording_surface = (cairo_recording_surface_t *) source;
|
||||
cairo_box_t bbox;
|
||||
|
||||
*width = extents.width;
|
||||
*height = extents.height;
|
||||
status = _cairo_recording_surface_get_bbox (recording_surface, &bbox, NULL);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_box_round_to_rectangle (&bbox, &extents);
|
||||
|
||||
*width = extents.width;
|
||||
*height = extents.height;
|
||||
}
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -2242,14 +2251,80 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
|
|||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_recording_subsurface (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_t *recording_surface,
|
||||
const cairo_rectangle_int_t *extents,
|
||||
cairo_pdf_resource_t resource)
|
||||
{
|
||||
double old_width, old_height;
|
||||
cairo_paginated_mode_t old_paginated_mode;
|
||||
cairo_status_t status;
|
||||
int alpha = 0;
|
||||
|
||||
old_width = surface->width;
|
||||
old_height = surface->height;
|
||||
old_paginated_mode = surface->paginated_mode;
|
||||
|
||||
_cairo_pdf_surface_set_size_internal (surface,
|
||||
extents->width,
|
||||
extents->height);
|
||||
/* Patterns are emitted after fallback images. The paginated mode
|
||||
* needs to be set to _RENDER while the recording surface is replayed
|
||||
* back to this surface.
|
||||
*/
|
||||
surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER;
|
||||
_cairo_pdf_group_resources_clear (&surface->resources);
|
||||
status = _cairo_pdf_surface_open_content_stream (surface, &resource, TRUE);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
if (cairo_surface_get_content (recording_surface) == CAIRO_CONTENT_COLOR) {
|
||||
status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_output_stream_printf (surface->output,
|
||||
"q /a%d gs 0 0 0 rg 0 0 %f %f re f Q\n",
|
||||
alpha,
|
||||
surface->width,
|
||||
surface->height);
|
||||
}
|
||||
|
||||
status = _cairo_recording_surface_replay_region (recording_surface,
|
||||
extents,
|
||||
&surface->base,
|
||||
CAIRO_RECORDING_REGION_NATIVE);
|
||||
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_close_content_stream (surface);
|
||||
|
||||
_cairo_pdf_surface_set_size_internal (surface,
|
||||
old_width,
|
||||
old_height);
|
||||
surface->paginated_mode = old_paginated_mode;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_surface (cairo_pdf_surface_t *surface,
|
||||
cairo_pdf_source_surface_t *src_surface)
|
||||
{
|
||||
if (_cairo_surface_is_recording (src_surface->surface)) {
|
||||
return _cairo_pdf_surface_emit_recording_surface (surface,
|
||||
src_surface->surface,
|
||||
src_surface->hash_entry->surface_res);
|
||||
if (src_surface->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
|
||||
if (src_surface->surface->backend->type == CAIRO_INTERNAL_SURFACE_TYPE_SUBSURFACE) {
|
||||
cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) src_surface->surface;
|
||||
return _cairo_pdf_surface_emit_recording_subsurface (surface,
|
||||
sub->target,
|
||||
&sub->extents,
|
||||
src_surface->hash_entry->surface_res);
|
||||
} else {
|
||||
return _cairo_pdf_surface_emit_recording_surface (surface,
|
||||
src_surface->surface,
|
||||
src_surface->hash_entry->surface_res);
|
||||
}
|
||||
} else {
|
||||
return _cairo_pdf_surface_emit_image_surface (surface,
|
||||
src_surface->surface,
|
||||
|
|
@ -2276,7 +2351,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
|||
char draw_surface[200];
|
||||
|
||||
if (pattern->base.extend == CAIRO_EXTEND_PAD &&
|
||||
! _cairo_surface_is_recording (pattern->surface))
|
||||
pattern->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
|
||||
{
|
||||
status = _cairo_pdf_surface_emit_padded_image_surface (surface,
|
||||
pdf_pattern,
|
||||
|
|
@ -2407,7 +2482,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
|||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
if (_cairo_surface_is_recording (pattern->surface)) {
|
||||
if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
|
||||
snprintf(draw_surface,
|
||||
sizeof (draw_surface),
|
||||
"/x%d Do\n",
|
||||
|
|
@ -3278,7 +3353,7 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
|
|||
cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &pdf_p2d);
|
||||
cairo_matrix_translate (&pdf_p2d, 0.0, height);
|
||||
cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
|
||||
if (! _cairo_surface_is_recording (source->surface))
|
||||
if (source->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
|
||||
cairo_matrix_scale (&pdf_p2d, width, height);
|
||||
|
||||
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
||||
|
|
@ -5076,7 +5151,7 @@ _surface_pattern_supported (cairo_surface_pattern_t *pattern)
|
|||
{
|
||||
cairo_extend_t extend;
|
||||
|
||||
if (_cairo_surface_is_recording (pattern->surface))
|
||||
if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
|
||||
return TRUE;
|
||||
|
||||
if (pattern->surface->backend->acquire_source_image == NULL)
|
||||
|
|
@ -5216,7 +5291,7 @@ _cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t *surface,
|
|||
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
|
||||
|
||||
if ( _cairo_surface_is_recording (surface_pattern->surface)) {
|
||||
if (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
|
||||
if (pattern->extend == CAIRO_EXTEND_PAD)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
else
|
||||
|
|
@ -5234,7 +5309,7 @@ _cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t *surface,
|
|||
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
|
||||
|
||||
if (_cairo_surface_is_recording (surface_pattern->surface)) {
|
||||
if (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
|
||||
if (_cairo_pattern_is_opaque (pattern, extents)) {
|
||||
return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN;
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue