mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-25 16:30:09 +01:00
pdf: fix mime-unique-id jpeg attached to recording test
- Restructure the emit_surface code so that mime types are checked first. - Add a test parameter to emit_surface to test if the surface will be emitted as an image or recording instead checking the surface type as the attached mime may override this. - Mark surface as not clear when mime is attached to avoid optimizing away "clear" surfaces that have mime attached. - Include entire surface in analysis if mime attached (also fixes bug with calculating the extents CONTENT_COLOR surfaces)
This commit is contained in:
parent
bff47b43c4
commit
d5cb45013b
5 changed files with 287 additions and 145 deletions
|
|
@ -137,81 +137,6 @@ detach_proxy (cairo_surface_t *proxy)
|
|||
cairo_surface_destroy (proxy);
|
||||
}
|
||||
|
||||
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_status_t status, analysis_status;
|
||||
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))
|
||||
return tmp->base.status;
|
||||
proxy = attach_proxy (source, &tmp->base);
|
||||
|
||||
p2d = pattern->matrix;
|
||||
status = cairo_matrix_invert (&p2d);
|
||||
assert (status == CAIRO_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 (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 if (source->content & CAIRO_CONTENT_ALPHA) {
|
||||
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);
|
||||
} else {
|
||||
/* black background fills entire extents */
|
||||
_cairo_surface_get_extents (source, extents);
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
@ -329,6 +254,103 @@ _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, analysis_status;
|
||||
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;
|
||||
|
||||
return analysis_status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_analysis_surface_finish (void *abstract_surface)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -267,6 +267,12 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
|
|||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface);
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_emit_surface (cairo_pdf_surface_t *surface,
|
||||
cairo_pdf_source_surface_t *source,
|
||||
cairo_bool_t test,
|
||||
cairo_bool_t *is_image);
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface);
|
||||
|
||||
|
|
@ -1646,6 +1652,11 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface,
|
|||
goto fail3;
|
||||
}
|
||||
|
||||
/* Test if surface will be emitted as image or recording */
|
||||
status = _cairo_pdf_surface_emit_surface (surface, &src_surface, TRUE, &surface_entry->emit_image);
|
||||
if (unlikely (status))
|
||||
goto fail3;
|
||||
|
||||
if (surface_entry->bounded) {
|
||||
status = _cairo_array_append (&surface->page_surfaces, &src_surface);
|
||||
if (unlikely (status))
|
||||
|
|
@ -2890,7 +2901,8 @@ _cairo_pdf_surface_lookup_jbig2_global (cairo_pdf_surface_t *surface,
|
|||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_emit_jbig2_image (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_t *source,
|
||||
cairo_pdf_source_surface_entry_t *surface_entry)
|
||||
cairo_pdf_source_surface_entry_t *surface_entry,
|
||||
cairo_bool_t test)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
const unsigned char *mime_data;
|
||||
|
|
@ -2913,6 +2925,10 @@ _cairo_pdf_surface_emit_jbig2_image (cairo_pdf_surface_t *surface,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
/* At this point we know emitting jbig2 will succeed. */
|
||||
if (test)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID,
|
||||
&global_id, &global_id_length);
|
||||
if (global_id && global_id_length > 0) {
|
||||
|
|
@ -2998,7 +3014,8 @@ _cairo_pdf_surface_emit_jbig2_image (cairo_pdf_surface_t *surface,
|
|||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_t *source,
|
||||
cairo_pdf_source_surface_entry_t *surface_entry)
|
||||
cairo_pdf_source_surface_entry_t *surface_entry,
|
||||
cairo_bool_t test)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
const unsigned char *mime_data;
|
||||
|
|
@ -3029,6 +3046,10 @@ _cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface,
|
|||
else
|
||||
smask_buf[0] = 0;
|
||||
|
||||
/* At this point we know emitting jpx will succeed. */
|
||||
if (test)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (surface_entry->stencil_mask) {
|
||||
status = _cairo_pdf_surface_open_stream (surface,
|
||||
&surface_entry->surface_res,
|
||||
|
|
@ -3073,7 +3094,8 @@ _cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface,
|
|||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_t *source,
|
||||
cairo_pdf_source_surface_entry_t *surface_entry)
|
||||
cairo_pdf_source_surface_entry_t *surface_entry,
|
||||
cairo_bool_t test)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
const unsigned char *mime_data;
|
||||
|
|
@ -3113,6 +3135,10 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
|
|||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* At this point we know emitting jpeg will succeed. */
|
||||
if (test)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (surface_entry->smask_res.id)
|
||||
snprintf(smask_buf, sizeof(smask_buf), " /SMask %d 0 R\n", surface_entry->smask_res.id);
|
||||
else
|
||||
|
|
@ -3168,7 +3194,8 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
|
|||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_emit_ccitt_image (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_t *source,
|
||||
cairo_pdf_source_surface_entry_t *surface_entry)
|
||||
cairo_pdf_source_surface_entry_t *surface_entry,
|
||||
cairo_bool_t test)
|
||||
{
|
||||
cairo_status_t status;
|
||||
const unsigned char *ccitt_data;
|
||||
|
|
@ -3203,6 +3230,10 @@ _cairo_pdf_surface_emit_ccitt_image (cairo_pdf_surface_t *surface,
|
|||
|
||||
free (params);
|
||||
|
||||
/* At this point we know emitting jbig2 will succeed. */
|
||||
if (test)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
p = buf;
|
||||
*p = 0;
|
||||
end = buf + sizeof(buf) - 1;
|
||||
|
|
@ -3272,54 +3303,6 @@ _cairo_pdf_surface_emit_ccitt_image (cairo_pdf_surface_t *surface,
|
|||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
|
||||
cairo_pdf_source_surface_t *source)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
status = _cairo_pdf_surface_emit_jbig2_image (surface, source->surface, source->hash_entry);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_emit_jpx_image (surface, source->surface, source->hash_entry);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_emit_jpeg_image (surface, source->surface, source->hash_entry);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_emit_ccitt_image (surface, source->surface, source->hash_entry);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
status = _cairo_surface_acquire_source_image (source->surface, &image, &image_extra);
|
||||
} else {
|
||||
status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source->raster_pattern,
|
||||
&image, &image_extra);
|
||||
}
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_emit_image (surface,
|
||||
image,
|
||||
source->hash_entry);
|
||||
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SURFACE)
|
||||
_cairo_surface_release_source_image (source->surface, image, image_extra);
|
||||
else
|
||||
_cairo_pdf_surface_release_source_image_from_pattern (surface, source->raster_pattern,
|
||||
image, image_extra);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
|
||||
cairo_pdf_source_surface_t *pdf_source)
|
||||
|
|
@ -3441,15 +3424,107 @@ err:
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_pdf_surface_emit_surface:
|
||||
* @surface: [in] the pdf surface
|
||||
* @source: [in] #cairo_pdf_source_surface_t containing the surface to write
|
||||
* @test: [in] if true, test what type of surface will be emitted.
|
||||
* @is_image: [out] if @test is true, returns TRUE if the surface will be emitted
|
||||
* as an Image XObject.
|
||||
*
|
||||
* If @test is FALSE, emit @src_surface as an XObject.
|
||||
* If @test is TRUE, don't emit anything. Set @is_image based on the output that would be emitted.
|
||||
**/
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_emit_surface (cairo_pdf_surface_t *surface,
|
||||
cairo_pdf_source_surface_t *src_surface)
|
||||
cairo_pdf_source_surface_t *source,
|
||||
cairo_bool_t test,
|
||||
cairo_bool_t *is_image)
|
||||
{
|
||||
if (src_surface->type == CAIRO_PATTERN_TYPE_SURFACE &&
|
||||
src_surface->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
|
||||
return _cairo_pdf_surface_emit_recording_surface (surface, src_surface);
|
||||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
cairo_int_status_t status;
|
||||
|
||||
return _cairo_pdf_surface_emit_image_surface (surface, src_surface);
|
||||
/* Try all the supported mime types and recording type, falling through
|
||||
* each option if unsupported */
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
status = _cairo_pdf_surface_emit_jbig2_image (surface,
|
||||
source->surface,
|
||||
source->hash_entry,
|
||||
test);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
*is_image = TRUE;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_pdf_surface_emit_jpx_image (surface,
|
||||
source->surface,
|
||||
source->hash_entry,
|
||||
test);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
*is_image = TRUE;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_pdf_surface_emit_jpeg_image (surface,
|
||||
source->surface,
|
||||
source->hash_entry,
|
||||
test);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
*is_image = TRUE;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_pdf_surface_emit_ccitt_image (surface,
|
||||
source->surface,
|
||||
source->hash_entry,
|
||||
test);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
*is_image = TRUE;
|
||||
return status;
|
||||
}
|
||||
|
||||
if (source->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
|
||||
if (test) {
|
||||
*is_image = FALSE;
|
||||
return CAIRO_INT_STATUS_SUCCESS;
|
||||
} else {
|
||||
return _cairo_pdf_surface_emit_recording_surface (surface, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The only option left is to emit as an image surface */
|
||||
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
status = _cairo_surface_acquire_source_image (source->surface, &image, &image_extra);
|
||||
} else {
|
||||
status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface,
|
||||
source->raster_pattern,
|
||||
&image,
|
||||
&image_extra);
|
||||
}
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
if (test) {
|
||||
*is_image = TRUE;
|
||||
} else {
|
||||
status = _cairo_pdf_surface_emit_image (surface,
|
||||
image,
|
||||
source->hash_entry);
|
||||
}
|
||||
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
_cairo_surface_release_source_image (source->surface, image, image_extra);
|
||||
} else {
|
||||
_cairo_pdf_surface_release_source_image_from_pattern (surface,
|
||||
source->raster_pattern,
|
||||
image,
|
||||
image_extra);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
|
|
@ -3596,8 +3671,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
|||
|
||||
cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &mat);
|
||||
cairo_matrix_translate (&pdf_p2d, x_offset, y_offset);
|
||||
if (((cairo_surface_pattern_t *)pattern)->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
|
||||
{
|
||||
if (pdf_source->emit_image) {
|
||||
cairo_matrix_translate (&pdf_p2d, 0.0, pdf_source->extents.height);
|
||||
cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
|
||||
}
|
||||
|
|
@ -3625,18 +3699,18 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
|||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
if (((cairo_surface_pattern_t *) pattern)->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
|
||||
snprintf(draw_surface,
|
||||
sizeof (draw_surface),
|
||||
"/x%d Do",
|
||||
pdf_source->surface_res.id);
|
||||
} else {
|
||||
if (pdf_source->emit_image) {
|
||||
snprintf(draw_surface,
|
||||
sizeof (draw_surface),
|
||||
"q %d 0 0 %d 0 0 cm /x%d Do Q",
|
||||
pdf_source->extents.width,
|
||||
pdf_source->extents.height,
|
||||
pdf_source->surface_res.id);
|
||||
} else {
|
||||
snprintf(draw_surface,
|
||||
sizeof (draw_surface),
|
||||
"/x%d Do",
|
||||
pdf_source->surface_res.id);
|
||||
}
|
||||
|
||||
if (extend == CAIRO_EXTEND_REFLECT) {
|
||||
|
|
@ -6729,6 +6803,7 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
|
|||
cairo_pdf_source_surface_t src_surface;
|
||||
unsigned int pattern_index, group_index, surface_index, doc_surface_index;
|
||||
cairo_int_status_t status;
|
||||
cairo_bool_t is_image;
|
||||
|
||||
/* Writing out PDF_MASK groups will cause additional smask groups
|
||||
* to be appended to surface->smask_groups. Additional patterns
|
||||
|
|
@ -6762,7 +6837,7 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
|
|||
|
||||
for (; surface_index < _cairo_array_num_elements (&surface->page_surfaces); surface_index++) {
|
||||
_cairo_array_copy_element (&surface->page_surfaces, surface_index, &src_surface);
|
||||
status = _cairo_pdf_surface_emit_surface (surface, &src_surface);
|
||||
status = _cairo_pdf_surface_emit_surface (surface, &src_surface, FALSE, &is_image);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
|
|
@ -6770,7 +6845,7 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
|
|||
if (finish) {
|
||||
for (; doc_surface_index < _cairo_array_num_elements (&surface->doc_surfaces); doc_surface_index++) {
|
||||
_cairo_array_copy_element (&surface->doc_surfaces, doc_surface_index, &src_surface);
|
||||
status = _cairo_pdf_surface_emit_surface (surface, &src_surface);
|
||||
status = _cairo_pdf_surface_emit_surface (surface, &src_surface, FALSE, &is_image);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
|
|
@ -6915,7 +6990,7 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_analyze_surface_pattern_transparency (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_pattern_t *pattern)
|
||||
cairo_surface_pattern_t *pattern)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
|
|
|
|||
|
|
@ -1224,6 +1224,44 @@ _cairo_mime_data_destroy (void *ptr)
|
|||
free (mime_data);
|
||||
}
|
||||
|
||||
|
||||
static const char *_cairo_surface_image_mime_types[] = {
|
||||
CAIRO_MIME_TYPE_JPEG,
|
||||
CAIRO_MIME_TYPE_PNG,
|
||||
CAIRO_MIME_TYPE_JP2,
|
||||
CAIRO_MIME_TYPE_JBIG2,
|
||||
CAIRO_MIME_TYPE_CCITT_FAX,
|
||||
};
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_surface_has_mime_image (cairo_surface_t *surface)
|
||||
{
|
||||
cairo_user_data_slot_t *slots;
|
||||
int i, j, num_slots;
|
||||
|
||||
/* Prevent reads of the array during teardown */
|
||||
if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
|
||||
return FALSE;
|
||||
|
||||
/* The number of mime-types attached to a surface is usually small,
|
||||
* typically zero. Therefore it is quicker to do a strcmp() against
|
||||
* each key than it is to intern the string (i.e. compute a hash,
|
||||
* search the hash table, and do a final strcmp).
|
||||
*/
|
||||
num_slots = surface->mime_data.num_elements;
|
||||
slots = _cairo_array_index (&surface->mime_data, 0);
|
||||
for (i = 0; i < num_slots; i++) {
|
||||
if (slots[i].key != NULL) {
|
||||
for (j = 0; j < ARRAY_LENGTH (_cairo_surface_image_mime_types); j++) {
|
||||
if (strcmp ((char *) slots[i].key, _cairo_surface_image_mime_types[j]) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* CAIRO_MIME_TYPE_CCITT_FAX:
|
||||
*
|
||||
|
|
@ -1405,6 +1443,8 @@ cairo_surface_set_mime_data (cairo_surface_t *surface,
|
|||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
surface->is_clear = FALSE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
slim_hidden_def (cairo_surface_set_mime_data);
|
||||
|
|
@ -1479,6 +1519,8 @@ _cairo_surface_copy_mime_data (cairo_surface_t *dst,
|
|||
_cairo_mime_data_reference,
|
||||
NULL);
|
||||
|
||||
dst->is_clear = FALSE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1336,6 +1336,9 @@ _cairo_stroke_style_dash_approximate (const cairo_stroke_style_t *style,
|
|||
|
||||
/* cairo-surface.c */
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_has_mime_image (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_copy_mime_data (cairo_surface_t *dst,
|
||||
cairo_surface_t *src);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@
|
|||
* file size due to changes to the PS/PDF surfaces while being small
|
||||
* enough to catch any attempt to embed the surface more than
|
||||
* once. The compressed size of each surface embedded in PDF is:
|
||||
* - image: 111,952
|
||||
* - image: 108,774
|
||||
* - jpeg: 11,400
|
||||
* - recording: 17,518
|
||||
*
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
*/
|
||||
#define PS2_EXPECTED_SIZE 315362
|
||||
#define PS3_EXPECTED_SIZE 315362
|
||||
#define PDF_EXPECTED_SIZE 142968
|
||||
#define PDF_EXPECTED_SIZE 347182
|
||||
#define SIZE_TOLERANCE 5000
|
||||
|
||||
static const char *png_filename = "romedalen.png";
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue