summaryrefslogtreecommitdiff
path: root/src/cairo-pdf-surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo-pdf-surface.c')
-rw-r--r--src/cairo-pdf-surface.c723
1 files changed, 514 insertions, 209 deletions
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index b2a5619e..5862c4b5 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -45,6 +45,7 @@
#include "cairo-pdf-surface-private.h"
#include "cairo-pdf-operators-private.h"
#include "cairo-analysis-surface-private.h"
+#include "cairo-image-info-private.h"
#include "cairo-meta-surface-private.h"
#include "cairo-output-stream-private.h"
#include "cairo-paginated-private.h"
@@ -110,6 +111,20 @@
* XObject instead of using an indirect object.
*/
+static const cairo_pdf_version_t _cairo_pdf_versions[] =
+{
+ CAIRO_PDF_VERSION_1_4,
+ CAIRO_PDF_VERSION_1_5
+};
+
+#define CAIRO_PDF_VERSION_LAST ARRAY_LENGTH (_cairo_pdf_versions)
+
+static const char * _cairo_pdf_version_strings[CAIRO_PDF_VERSION_LAST] =
+{
+ "PDF 1.4",
+ "PDF 1.5"
+};
+
typedef struct _cairo_pdf_object {
long offset;
} cairo_pdf_object_t;
@@ -192,7 +207,7 @@ _cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface)
object.offset = _cairo_output_stream_get_position (surface->output);
status = _cairo_array_append (&surface->objects, &object);
- if (status) {
+ if (unlikely (status)) {
resource.id = 0;
return resource;
}
@@ -234,7 +249,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
cairo_status_t status, status_ignored;
surface = malloc (sizeof (cairo_pdf_surface_t));
- if (surface == NULL) {
+ if (unlikely (surface == NULL)) {
/* destroy stream on behalf of caller */
status = _cairo_output_stream_destroy (output);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -272,6 +287,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
goto BAIL1;
}
+ surface->pdf_version = CAIRO_PDF_VERSION_1_5;
surface->compress_content = TRUE;
surface->pdf_stream.active = FALSE;
surface->pdf_stream.old_output = NULL;
@@ -284,6 +300,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
surface->force_fallbacks = FALSE;
surface->select_pattern_gstate_saved = FALSE;
surface->current_pattern_is_solid_color = FALSE;
+ surface->header_emitted = FALSE;
_cairo_pdf_operators_init (&surface->pdf_operators,
surface->output,
@@ -292,12 +309,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
_cairo_pdf_operators_set_font_subsets_callback (&surface->pdf_operators,
_cairo_pdf_surface_add_font,
surface);
-
- /* Document header */
- _cairo_output_stream_printf (surface->output,
- "%%PDF-1.4\n");
- _cairo_output_stream_printf (surface->output,
- "%%%c%c%c%c\n", 181, 237, 174, 251);
+ _cairo_pdf_operators_enable_actual_text(&surface->pdf_operators, TRUE);
surface->paginated_surface = _cairo_paginated_surface_create (
&surface->base,
@@ -437,6 +449,83 @@ _extract_pdf_surface (cairo_surface_t *surface,
}
/**
+ * cairo_pdf_surface_restrict_to_version:
+ * @surface: a PDF #cairo_surface_t
+ * @version: PDF version
+ *
+ * Restricts the generated PDF file to @version. See cairo_pdf_get_versions()
+ * for a list of available version values that can be used here.
+ *
+ * This function should only be called before any drawing operations
+ * have been performed on the given surface. The simplest way to do
+ * this is to call this function immediately after creating the
+ * surface.
+ *
+ * Since: 1.10
+ **/
+void
+cairo_pdf_surface_restrict_to_version (cairo_surface_t *abstract_surface,
+ cairo_pdf_version_t version)
+{
+ cairo_pdf_surface_t *surface = NULL; /* hide compiler warning */
+ cairo_status_t status;
+
+ status = _extract_pdf_surface (abstract_surface, &surface);
+ if (status) {
+ status = _cairo_surface_set_error (abstract_surface, status);
+ return;
+ }
+
+ if (version < CAIRO_PDF_VERSION_LAST)
+ surface->pdf_version = version;
+
+ _cairo_pdf_operators_enable_actual_text(&surface->pdf_operators,
+ version >= CAIRO_PDF_VERSION_1_5);
+}
+
+/**
+ * cairo_pdf_get_versions:
+ * @versions: supported version list
+ * @num_versions: list length
+ *
+ * Used to retrieve the list of supported versions. See
+ * cairo_pdf_surface_restrict_to_version().
+ *
+ * Since: 1.10
+ **/
+void
+cairo_pdf_get_versions (cairo_pdf_version_t const **versions,
+ int *num_versions)
+{
+ if (versions != NULL)
+ *versions = _cairo_pdf_versions;
+
+ if (num_versions != NULL)
+ *num_versions = CAIRO_PDF_VERSION_LAST;
+}
+
+/**
+ * cairo_pdf_version_to_string:
+ * @version: a version id
+ *
+ * Get the string representation of the given @version id. This function
+ * will return %NULL if @version isn't valid. See cairo_pdf_get_versions()
+ * for a way to get the list of valid version ids.
+ *
+ * Return value: the string associated to given version.
+ *
+ * Since: 1.10
+ **/
+const char *
+cairo_pdf_version_to_string (cairo_pdf_version_t version)
+{
+ if (version >= CAIRO_PDF_VERSION_LAST)
+ return NULL;
+
+ return _cairo_pdf_version_strings[version];
+}
+
+/**
* cairo_pdf_surface_set_size:
* @surface: a PDF #cairo_surface_t
* @width_in_points: new surface width, in points (1 point == 1/72.0 inch)
@@ -462,7 +551,7 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface,
cairo_status_t status;
status = _extract_pdf_surface (surface, &pdf_surface);
- if (status) {
+ if (unlikely (status)) {
status = _cairo_surface_set_error (surface, status);
return;
}
@@ -473,7 +562,7 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface,
status = _cairo_paginated_surface_set_size (pdf_surface->paginated_surface,
width_in_points,
height_in_points);
- if (status)
+ if (unlikely (status))
status = _cairo_surface_set_error (surface, status);
}
@@ -550,7 +639,7 @@ _cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface,
}
status = _cairo_array_append (&res->alphas, &alpha);
- if (status)
+ if (unlikely (status))
return status;
*index = _cairo_array_num_elements (&res->alphas) - 1;
@@ -613,7 +702,7 @@ _cairo_pdf_surface_add_font (unsigned int font_id,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_array_append (&surface->fonts, &font);
- if (status)
+ if (unlikely (status))
return status;
return _cairo_array_append (&res->fonts, &font);
@@ -728,7 +817,7 @@ _cairo_pdf_surface_create_smask_group (cairo_pdf_surface_t *surface)
cairo_pdf_smask_group_t *group;
group = calloc (1, sizeof (cairo_pdf_smask_group_t));
- if (group == NULL) {
+ if (unlikely (group == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
@@ -775,6 +864,7 @@ _cairo_pdf_surface_add_smask_group (cairo_pdf_surface_t *surface,
static cairo_status_t
_cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
const cairo_pattern_t *pattern,
+ cairo_rectangle_int_t *extents,
cairo_pdf_resource_t *pattern_res,
cairo_pdf_resource_t *gstate_res)
{
@@ -808,7 +898,7 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
}
status = _cairo_pattern_create_copy (&pdf_pattern.pattern, pattern);
- if (status)
+ if (unlikely (status))
return status;
pdf_pattern.pattern_res = _cairo_pdf_surface_new_object (surface);
@@ -833,11 +923,20 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
pdf_pattern.width = surface->width;
pdf_pattern.height = surface->height;
+ if (extents) {
+ pdf_pattern.extents = *extents;
+ } else {
+ pdf_pattern.extents.x = 0;
+ pdf_pattern.extents.y = 0;
+ pdf_pattern.extents.width = surface->width;
+ pdf_pattern.extents.height = surface->height;
+ }
+
*pattern_res = pdf_pattern.pattern_res;
*gstate_res = pdf_pattern.gstate_res;
status = _cairo_array_append (&surface->patterns, &pdf_pattern);
- if (status) {
+ if (unlikely (status)) {
cairo_pattern_destroy (pdf_pattern.pattern);
return status;
}
@@ -923,7 +1022,7 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
return CAIRO_STATUS_SUCCESS;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
if (surface->pdf_stream.compressed) {
@@ -1052,7 +1151,7 @@ _cairo_pdf_surface_open_knockout_group (cairo_pdf_surface_t *surface)
cairo_status_t status;
status = _cairo_pdf_surface_open_group (surface, NULL);
- if (status)
+ if (unlikely (status))
return status;
surface->group_stream.is_knockout = TRUE;
@@ -1070,7 +1169,7 @@ _cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
assert (surface->group_stream.active == TRUE);
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
if (surface->compress_content) {
@@ -1138,7 +1237,7 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
surface->compress_content,
NULL);
}
- if (status)
+ if (unlikely (status))
return status;
surface->content = surface->pdf_stream.self;
@@ -1157,12 +1256,12 @@ _cairo_pdf_surface_close_content_stream (cairo_pdf_surface_t *surface)
assert (surface->group_stream.active == FALSE);
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output, "Q\n");
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
_cairo_pdf_surface_update_object (surface, surface->content_resources);
@@ -1280,6 +1379,27 @@ _cairo_pdf_surface_start_page (void *abstract_surface)
{
cairo_pdf_surface_t *surface = abstract_surface;
+ /* Document header */
+ if (! surface->header_emitted) {
+ const char *version;
+
+ switch (surface->pdf_version) {
+ case CAIRO_PDF_VERSION_1_4:
+ version = "1.4";
+ break;
+ default:
+ case CAIRO_PDF_VERSION_1_5:
+ version = "1.5";
+ break;
+ }
+
+ _cairo_output_stream_printf (surface->output,
+ "%%PDF-%s\n", version);
+ _cairo_output_stream_printf (surface->output,
+ "%%%c%c%c%c\n", 181, 237, 174, 251);
+ surface->header_emitted = TRUE;
+ }
+
_cairo_pdf_group_resources_clear (&surface->resources);
return CAIRO_STATUS_SUCCESS;
@@ -1294,7 +1414,7 @@ _cairo_pdf_surface_has_fallback_images (void *abstract_surface,
surface->has_fallback_images = has_fallbacks;
status = _cairo_pdf_surface_open_content_stream (surface, has_fallbacks);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -1341,7 +1461,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
alpha = _cairo_malloc_ab (image->height, image->width);
}
- if (alpha == NULL) {
+ if (unlikely (alpha == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP;
}
@@ -1395,7 +1515,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
" /BitsPerComponent %d\n",
image->width, image->height,
image->format == CAIRO_FORMAT_A1 ? 1 : 8);
- if (status)
+ if (unlikely (status))
goto CLEANUP_ALPHA;
*stream_ret = surface->pdf_stream.self;
@@ -1437,7 +1557,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
rgb_size = image->height * image->width * 3;
rgb = _cairo_malloc_abc (image->width, image->height, 3);
- if (rgb == NULL) {
+ if (unlikely (rgb == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP;
}
@@ -1481,7 +1601,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
image->format == CAIRO_FORMAT_A8 ||
image->format == CAIRO_FORMAT_A1) {
status = _cairo_pdf_surface_emit_smask (surface, image, &smask);
- if (status)
+ if (unlikely (status))
goto CLEANUP_RGB;
if (smask.id)
@@ -1525,7 +1645,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
IMAGE_DICTIONARY,
image->width, image->height,
interpolate);
- if (status)
+ if (unlikely (status))
goto CLEANUP_RGB;
#undef IMAGE_DICTIONARY
@@ -1540,27 +1660,188 @@ CLEANUP:
return status;
}
+static cairo_int_status_t
+_cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface,
+ cairo_surface_t *source,
+ cairo_pdf_resource_t *res,
+ int *width,
+ int *height)
+{
+ cairo_status_t status;
+ const unsigned char *mime_data;
+ unsigned int mime_data_length;
+ cairo_image_info_t info;
+
+ if (surface->pdf_version < CAIRO_PDF_VERSION_1_5)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JP2,
+ &mime_data, &mime_data_length);
+ if (mime_data == NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ status = _cairo_image_info_get_jpx_info (&info, mime_data, mime_data_length);
+ if (status)
+ return status;
+
+ status = _cairo_pdf_surface_open_stream (surface,
+ NULL,
+ FALSE,
+ " /Type /XObject\n"
+ " /Subtype /Image\n"
+ " /Width %d\n"
+ " /Height %d\n"
+ " /ColorSpace /DeviceRGB\n"
+ " /Filter /JPXDecode\n",
+ info.width,
+ info.height);
+ if (status)
+ return status;
+
+ *res = surface->pdf_stream.self;
+ _cairo_output_stream_write (surface->output, mime_data, mime_data_length);
+ _cairo_output_stream_printf (surface->output, "\n");
+ status = _cairo_pdf_surface_close_stream (surface);
+
+ *width = info.width;
+ *height = info.height;
+
+ return status;
+}
+
+static cairo_int_status_t
+_cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
+ cairo_surface_t *source,
+ cairo_pdf_resource_t *res,
+ int *width,
+ int *height)
+{
+ cairo_status_t status;
+ const unsigned char *mime_data;
+ unsigned int mime_data_length;
+ cairo_image_info_t info;
+
+ cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
+ &mime_data, &mime_data_length);
+ if (mime_data == NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ status = _cairo_image_info_get_jpeg_info (&info, mime_data, mime_data_length);
+ if (unlikely (status))
+ return status;
+
+ if (info.num_components != 1 && info.num_components != 3)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ status = _cairo_pdf_surface_open_stream (surface,
+ NULL,
+ FALSE,
+ " /Type /XObject\n"
+ " /Subtype /Image\n"
+ " /Width %d\n"
+ " /Height %d\n"
+ " /ColorSpace %s\n"
+ " /BitsPerComponent %d\n"
+ " /Filter /DCTDecode\n",
+ info.width,
+ info.height,
+ info.num_components == 1 ? "/DeviceGray" : "/DeviceRGB",
+ info.bits_per_component);
+ if (unlikely (status))
+ return status;
+
+ *res = surface->pdf_stream.self;
+ _cairo_output_stream_write (surface->output, mime_data, mime_data_length);
+ _cairo_output_stream_printf (surface->output, "\n");
+ status = _cairo_pdf_surface_close_stream (surface);
+
+ *width = info.width;
+ *height = info.height;
+
+ return status;
+}
+
static cairo_status_t
_cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
- cairo_surface_pattern_t *pattern,
+ cairo_pdf_pattern_t *pdf_pattern,
cairo_pdf_resource_t *resource,
int *width,
- int *height)
+ int *height,
+ int *origin_x,
+ int *origin_y)
{
cairo_image_surface_t *image;
+ cairo_surface_t *pad_image;
void *image_extra;
cairo_status_t status;
+ cairo_surface_pattern_t *pattern = (cairo_surface_pattern_t *) pdf_pattern->pattern;
+ int x = 0;
+ int y = 0;
+
+ status = _cairo_pdf_surface_emit_jpx_image (surface, pattern->surface,
+ resource, width, height);
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
+
+ status = _cairo_pdf_surface_emit_jpeg_image (surface, pattern->surface,
+ resource, width, height);
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
- if (status)
+ if (unlikely (status))
goto BAIL;
- status = _cairo_pdf_surface_emit_image (surface, image, resource, pattern->base.filter);
- if (status)
+ pad_image = &image->base;
+ if (cairo_pattern_get_extend (&pattern->base) == CAIRO_EXTEND_PAD) {
+ cairo_box_t box;
+ cairo_rectangle_int_t rect;
+ cairo_surface_pattern_t pad_pattern;
+
+ /* get the operation extents in pattern space */
+ _cairo_box_from_rectangle (&box, &pdf_pattern->extents);
+ _cairo_matrix_transform_bounding_box_fixed (&pattern->base.matrix, &box, NULL);
+ _cairo_box_round_to_rectangle (&box, &rect);
+ x = -rect.x;
+ y = -rect.y;
+
+ pad_image = _cairo_image_surface_create_with_content (pattern->surface->content,
+ rect.width,
+ rect.height);
+ if (pad_image->status) {
+ status = pad_image->status;
+ goto BAIL;
+ }
+
+ _cairo_pattern_init_for_surface (&pad_pattern, &image->base);
+ cairo_matrix_init_translate (&pad_pattern.base.matrix, -x, -y);
+ pad_pattern.base.extend = CAIRO_EXTEND_PAD;
+ status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
+ &pad_pattern.base,
+ NULL,
+ pad_image,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ rect.width,
+ rect.height);
+ _cairo_pattern_fini (&pad_pattern.base);
+ if (unlikely (status))
+ goto BAIL;
+ }
+
+ status = _cairo_pdf_surface_emit_image (surface, (cairo_image_surface_t *)pad_image,
+ resource, pattern->base.filter);
+ if (unlikely (status))
goto BAIL;
- *width = image->width;
- *height = image->height;
+ *width = ((cairo_image_surface_t *)pad_image)->width;
+ *height = ((cairo_image_surface_t *)pad_image)->height;
+ *origin_x = x;
+ *origin_y = y;
+
+ if (pad_image != &image->base)
+ cairo_surface_destroy (pad_image);
BAIL:
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
@@ -1581,7 +1862,7 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
int alpha = 0;
status = _cairo_surface_get_extents (meta_surface, &meta_extents);
- if (status)
+ if (unlikely (status))
return status;
old_width = surface->width;
@@ -1598,13 +1879,13 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER;
_cairo_pdf_group_resources_clear (&surface->resources);
status = _cairo_pdf_surface_open_content_stream (surface, TRUE);
- if (status)
+ if (unlikely (status))
return status;
*resource = surface->content;
if (cairo_surface_get_content (meta_surface) == CAIRO_CONTENT_COLOR) {
status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -1617,11 +1898,11 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
status = _cairo_meta_surface_replay_region (meta_surface, &surface->base,
CAIRO_META_REGION_NATIVE);
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_surface_set_clip (&surface->base, old_clip);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_close_content_stream (surface);
@@ -1647,6 +1928,8 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
cairo_rectangle_int_t surface_extents;
int pattern_width = 0; /* squelch bogus compiler warning */
int pattern_height = 0; /* squelch bogus compiler warning */
+ int origin_x = 0; /* squelch bogus compiler warning */
+ int origin_y = 0; /* squelch bogus compiler warning */
int bbox_x, bbox_y;
char draw_surface[200];
@@ -1657,33 +1940,34 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_emit_meta_surface (surface,
meta_surface,
&pattern_resource);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_surface_get_extents (meta_surface, &pattern_extents);
- if (status)
+ if (unlikely (status))
return status;
pattern_width = pattern_extents.width;
pattern_height = pattern_extents.height;
} else {
status = _cairo_pdf_surface_emit_image_surface (surface,
- pattern,
+ pdf_pattern,
&pattern_resource,
&pattern_width,
- &pattern_height);
- if (status)
+ &pattern_height,
+ &origin_x,
+ &origin_y);
+ if (unlikely (status))
return status;
}
status = _cairo_surface_get_extents (&surface->base, &surface_extents);
- if (status)
+ if (unlikely (status))
return status;
bbox_x = pattern_width;
bbox_y = pattern_height;
switch (extend) {
- /* We implement EXTEND_PAD like EXTEND_NONE for now */
case CAIRO_EXTEND_PAD:
case CAIRO_EXTEND_NONE:
{
@@ -1767,6 +2051,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
cairo_matrix_translate (&pdf_p2d, 0.0, surface_extents.height);
cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &pdf_p2d);
+ cairo_matrix_translate (&pdf_p2d, -origin_x, -origin_y);
cairo_matrix_translate (&pdf_p2d, 0.0, pattern_height);
cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
@@ -1789,7 +2074,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
pdf_p2d.x0, pdf_p2d.y0,
pattern_resource.id,
pattern_resource.id);
- if (status)
+ if (unlikely (status))
return status;
if (_cairo_surface_is_meta (pattern->surface)) {
@@ -1827,7 +2112,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
}
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
return _cairo_output_stream_get_status (surface->output);
@@ -1959,14 +2244,14 @@ _cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t *surface,
&stops[i],
&stops[i+1],
&stops[i].resource);
- if (status)
+ if (unlikely (status))
return status;
} else {
status = cairo_pdf_surface_emit_rgb_linear_function (surface,
&stops[i],
&stops[i+1],
&stops[i].resource);
- if (status)
+ if (unlikely (status))
return status;
}
}
@@ -2048,7 +2333,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
alpha_function->id = 0;
allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_pdf_color_stop_t));
- if (allstops == NULL)
+ if (unlikely (allstops == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
stops = &allstops[1];
@@ -2095,7 +2380,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
&stops[0],
&stops[1],
color_function);
- if (status)
+ if (unlikely (status))
goto BAIL;
if (emit_alpha) {
@@ -2103,7 +2388,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
&stops[0],
&stops[1],
alpha_function);
- if (status)
+ if (unlikely (status))
goto BAIL;
}
} else {
@@ -2114,7 +2399,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
stops,
FALSE,
color_function);
- if (status)
+ if (unlikely (status))
goto BAIL;
if (emit_alpha) {
@@ -2123,7 +2408,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface,
stops,
TRUE,
alpha_function);
- if (status)
+ if (unlikely (status))
goto BAIL;
}
}
@@ -2225,7 +2510,7 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
surface->height,
gradient_mask.id,
gradient_mask.id);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -2240,7 +2525,7 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
surface->height);
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
smask_resource = _cairo_pdf_surface_new_object (surface);
@@ -2363,7 +2648,7 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface,
&pattern->base,
&color_function,
&alpha_function);
- if (status)
+ if (unlikely (status))
return status;
if (pattern->base.base.extend == CAIRO_EXTEND_REPEAT ||
@@ -2373,7 +2658,7 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface,
&color_function,
repeat_begin,
repeat_end);
- if (status)
+ if (unlikely (status))
return status;
if (alpha_function.id != 0) {
@@ -2382,7 +2667,7 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface,
&alpha_function,
repeat_begin,
repeat_end);
- if (status)
+ if (unlikely (status))
return status;
}
}
@@ -2462,13 +2747,13 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface,
">>\n"
"endobj\n");
status = _cairo_pdf_surface_add_pattern (surface, mask_resource);
- if (status)
+ if (unlikely (status))
return status;
status = cairo_pdf_surface_emit_transparency_group (surface,
pdf_pattern->gstate_res,
mask_resource);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -2494,7 +2779,7 @@ _cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface,
&pattern->base,
&color_function,
&alpha_function);
- if (status)
+ if (unlikely (status))
return status;
pat_to_pdf = pattern->base.base.matrix;
@@ -2585,7 +2870,7 @@ _cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface,
status = cairo_pdf_surface_emit_transparency_group (surface,
pdf_pattern->gstate_res,
mask_resource);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -2668,7 +2953,7 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
surface->current_color_is_stroke != is_stroke)
{
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -2692,11 +2977,11 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
surface->current_color_alpha != solid_color->alpha)
{
status = _cairo_pdf_surface_add_alpha (surface, solid_color->alpha, &alpha);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -2708,15 +2993,15 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
surface->current_pattern_is_solid_color = TRUE;
} else {
status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_pattern (surface, pattern_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
/* fill-stroke calls select_pattern twice. Don't save if the
@@ -2750,7 +3035,7 @@ _cairo_pdf_surface_unselect_pattern (cairo_pdf_surface_t *surface)
if (surface->select_pattern_gstate_saved) {
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output, "Q\n");
@@ -2768,11 +3053,11 @@ _cairo_pdf_surface_show_page (void *abstract_surface)
cairo_int_status_t status;
status = _cairo_pdf_surface_close_content_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_write_page (surface);
- if (status)
+ if (unlikely (status))
return status;
_cairo_pdf_surface_clear (surface);
@@ -2811,7 +3096,7 @@ _cairo_pdf_surface_intersect_clip_path (void *abstract_surface,
if (path == NULL) {
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output, "Q q\n");
@@ -2898,7 +3183,7 @@ _cairo_pdf_surface_emit_unicode_for_glyph (cairo_pdf_surface_t *surface,
if (utf8 && *utf8) {
status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -2940,7 +3225,7 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface,
NULL,
surface->compress_content,
NULL);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -2992,7 +3277,7 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface,
}
status = _cairo_pdf_surface_emit_unicode_for_glyph (surface,
font_subset->utf8[i + 1]);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -3032,14 +3317,14 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface,
NULL,
TRUE,
" /Subtype /CIDFontType0C\n");
- if (status)
+ if (unlikely (status))
return status;
stream = surface->pdf_stream.self;
_cairo_output_stream_write (surface->output,
subset->data, subset->data_length);
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
@@ -3147,7 +3432,7 @@ _cairo_pdf_surface_emit_cff_font_subset (cairo_pdf_surface_t *surface,
snprintf (name, sizeof name, "CairoFont-%d-%d",
font_subset->font_id, font_subset->subset_id);
status = _cairo_cff_subset_init (&subset, name, font_subset);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset);
@@ -3168,7 +3453,7 @@ _cairo_pdf_surface_emit_cff_fallback_font (cairo_pdf_surface_t *surface,
snprintf (name, sizeof name, "CairoFont-%d-%d",
font_subset->font_id, font_subset->subset_id);
status = _cairo_cff_fallback_init (&subset, name, font_subset);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset);
@@ -3205,13 +3490,13 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
" /Length3 0\n",
subset->header_length,
subset->data_length);
- if (status)
+ if (unlikely (status))
return status;
stream = surface->pdf_stream.self;
_cairo_output_stream_write (surface->output, subset->data, length);
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
@@ -3299,7 +3584,7 @@ _cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface,
snprintf (name, sizeof name, "CairoFont-%d-%d",
font_subset->font_id, font_subset->subset_id);
status = _cairo_type1_subset_init (&subset, name, font_subset, FALSE);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset);
@@ -3320,7 +3605,7 @@ _cairo_pdf_surface_emit_type1_fallback_font (cairo_pdf_surface_t *surface,
snprintf (name, sizeof name, "CairoFont-%d-%d",
font_subset->font_id, font_subset->subset_id);
status = _cairo_type1_fallback_init_binary (&subset, name, font_subset);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset);
@@ -3349,7 +3634,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
status = _cairo_truetype_subset_init (&subset, font_subset);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_open_stream (surface,
@@ -3357,7 +3642,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
TRUE,
" /Length1 %lu\n",
subset.data_length);
- if (status) {
+ if (unlikely (status)) {
_cairo_truetype_subset_fini (&subset);
return status;
}
@@ -3366,7 +3651,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
_cairo_output_stream_write (surface->output,
subset.data, subset.data_length);
status = _cairo_pdf_surface_close_stream (surface);
- if (status) {
+ if (unlikely (status)) {
_cairo_truetype_subset_fini (&subset);
return status;
}
@@ -3537,7 +3822,7 @@ _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_su
for (i = 0; i < font_subset->num_glyphs; i++) {
status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface,
font_subset->glyphs[i]);
- if (status)
+ if (unlikely (status))
break;
}
@@ -3572,11 +3857,11 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
glyphs = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (cairo_pdf_resource_t));
- if (glyphs == NULL)
+ if (unlikely (glyphs == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
widths = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (double));
- if (widths == NULL) {
+ if (unlikely (widths == NULL)) {
free (glyphs);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -3595,7 +3880,7 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
NULL,
surface->compress_content,
NULL);
- if (status)
+ if (unlikely (status))
break;
glyphs[i] = surface->pdf_stream.self;
@@ -3604,11 +3889,11 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
font_subset->glyphs[i],
&bbox,
&widths[i]);
- if (status)
+ if (unlikely (status))
break;
status = _cairo_pdf_surface_close_stream (surface);
- if (status)
+ if (unlikely (status))
break;
if (i == 0) {
@@ -3628,7 +3913,7 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
}
}
cairo_surface_destroy (type3_surface);
- if (status) {
+ if (unlikely (status)) {
free (glyphs);
free (widths);
return status;
@@ -3787,19 +4072,19 @@ _cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface)
status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
_cairo_pdf_surface_analyze_user_font_subset,
surface);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets,
_cairo_pdf_surface_emit_unscaled_font_subset,
surface);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets,
_cairo_pdf_surface_emit_scaled_font_subset,
surface);
- if (status)
+ if (unlikely (status))
goto BAIL;
status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
@@ -3874,35 +4159,36 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
/* Create mask group */
status = _cairo_pdf_surface_open_group (surface, NULL);
- if (status)
+ if (unlikely (status))
return status;
pattern_res.id = 0;
gstate_res.id = 0;
- status = _cairo_pdf_surface_add_pdf_pattern (surface, group->mask, &pattern_res, &gstate_res);
- if (status)
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, group->mask, NULL,
+ &pattern_res, &gstate_res);
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
smask_group = _cairo_pdf_surface_create_smask_group (surface);
- if (smask_group == NULL)
+ if (unlikely (smask_group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
smask_group->operation = PDF_PAINT;
smask_group->source = cairo_pattern_reference (group->mask);
smask_group->source_res = pattern_res;
status = _cairo_pdf_surface_add_smask_group (surface, smask_group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (smask_group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, smask_group->group_res);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -3911,7 +4197,7 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
smask_group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, group->mask, pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -3919,45 +4205,46 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
surface->width, surface->height);
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
status = _cairo_pdf_surface_close_group (surface, &mask_group);
- if (status)
+ if (unlikely (status))
return status;
/* Create source group */
status = _cairo_pdf_surface_open_group (surface, &group->source_res);
- if (status)
+ if (unlikely (status))
return status;
pattern_res.id = 0;
gstate_res.id = 0;
- status = _cairo_pdf_surface_add_pdf_pattern (surface, group->source, &pattern_res, &gstate_res);
- if (status)
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, group->source, NULL,
+ &pattern_res, &gstate_res);
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
smask_group = _cairo_pdf_surface_create_smask_group (surface);
- if (smask_group == NULL)
+ if (unlikely (smask_group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
smask_group->operation = PDF_PAINT;
smask_group->source = cairo_pattern_reference (group->source);
smask_group->source_res = pattern_res;
status = _cairo_pdf_surface_add_smask_group (surface, smask_group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (smask_group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, smask_group->group_res);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -3966,7 +4253,7 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
smask_group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, group->source, pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -3974,12 +4261,12 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
surface->width, surface->height);
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
status = _cairo_pdf_surface_close_group (surface, NULL);
- if (status)
+ if (unlikely (status))
return status;
/* Create an smask based on the alpha component of mask_group */
@@ -4032,14 +4319,14 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
return _cairo_pdf_surface_write_mask_group (surface, group);
status = _cairo_pdf_surface_open_group (surface, &group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_select_pattern (surface,
group->source,
group->source_res,
group->operation == PDF_STROKE);
- if (status)
+ if (unlikely (status))
return status;
switch (group->operation) {
@@ -4072,11 +4359,11 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
group->scaled_font);
break;
}
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_close_group (surface, NULL);
@@ -4111,14 +4398,14 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
for (; group_index < _cairo_array_num_elements (&surface->smask_groups); group_index++) {
_cairo_array_copy_element (&surface->smask_groups, group_index, &group);
status = _cairo_pdf_surface_write_smask_group (surface, group);
- if (status)
+ if (unlikely (status))
return status;
}
for (; pattern_index < _cairo_array_num_elements (&surface->patterns); pattern_index++) {
_cairo_array_copy_element (&surface->patterns, pattern_index, &pattern);
status = _cairo_pdf_surface_emit_pattern (surface, &pattern);
- if (status)
+ if (unlikely (status))
return status;
}
}
@@ -4136,7 +4423,7 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
_cairo_pdf_group_resources_clear (&surface->resources);
if (surface->has_fallback_images) {
status = _cairo_pdf_surface_open_knockout_group (surface);
- if (status)
+ if (unlikely (status))
return status;
len = _cairo_array_num_elements (&surface->knockout_group);
@@ -4146,34 +4433,34 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
"/x%d Do\n",
res.id);
status = _cairo_pdf_surface_add_xobject (surface, res);
- if (status)
+ if (unlikely (status))
return status;
}
_cairo_output_stream_printf (surface->output,
"/x%d Do\n",
surface->content.id);
status = _cairo_pdf_surface_add_xobject (surface, surface->content);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_close_group (surface, &knockout);
- if (status)
+ if (unlikely (status))
return status;
_cairo_pdf_group_resources_clear (&surface->resources);
status = _cairo_pdf_surface_open_content_stream (surface, FALSE);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
"/x%d Do\n",
knockout.id);
status = _cairo_pdf_surface_add_xobject (surface, knockout);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_close_content_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4203,11 +4490,11 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
surface->content_resources.id);
status = _cairo_array_append (&surface->pages, &page);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_write_patterns_and_smask_groups (surface);
- if (status)
+ if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
@@ -4225,7 +4512,7 @@ _cairo_pdf_surface_analyze_surface_pattern_transparency (cairo_pdf_surface_t
status = _cairo_surface_acquire_source_image (pattern->surface,
&image,
&image_extra);
- if (status)
+ if (unlikely (status))
return status;
if (image->base.status)
@@ -4346,8 +4633,12 @@ _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_meta (surface_pattern->surface))
- return CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN;
+ if ( _cairo_surface_is_meta (surface_pattern->surface)) {
+ if (pattern->extend == CAIRO_EXTEND_PAD)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ else
+ return CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN;
+ }
}
}
@@ -4406,11 +4697,11 @@ _cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface)
cairo_status_t status;
status = _cairo_pdf_surface_close_content_stream (surface);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_array_append (&surface->knockout_group, &surface->content);
- if (status)
+ if (unlikely (status))
return status;
_cairo_pdf_group_resources_clear (&surface->resources);
@@ -4420,7 +4711,8 @@ _cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface)
static cairo_int_status_t
_cairo_pdf_surface_paint (void *abstract_surface,
cairo_operator_t op,
- const cairo_pattern_t *source)
+ const cairo_pattern_t *source,
+ cairo_rectangle_int_t *extents)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_status_t status;
@@ -4431,7 +4723,7 @@ _cairo_pdf_surface_paint (void *abstract_surface,
return _cairo_pdf_surface_analyze_operation (surface, op, source);
} else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
status = _cairo_pdf_surface_start_fallback (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4439,40 +4731,41 @@ _cairo_pdf_surface_paint (void *abstract_surface,
pattern_res.id = 0;
gstate_res.id = 0;
- status = _cairo_pdf_surface_add_pdf_pattern (surface, source, &pattern_res, &gstate_res);
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents,
+ &pattern_res, &gstate_res);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
group = _cairo_pdf_surface_create_smask_group (surface);
- if (group == NULL)
+ if (unlikely (group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_PAINT;
status = _cairo_pattern_create_copy (&group->source, source);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
group->source_res = pattern_res;
status = _cairo_pdf_surface_add_smask_group (surface, group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4481,7 +4774,7 @@ _cairo_pdf_surface_paint (void *abstract_surface,
group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4489,7 +4782,7 @@ _cairo_pdf_surface_paint (void *abstract_surface,
surface->width, surface->height);
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4500,7 +4793,8 @@ static cairo_int_status_t
_cairo_pdf_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
- const cairo_pattern_t *mask)
+ const cairo_pattern_t *mask,
+ cairo_rectangle_int_t *extents)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_pdf_smask_group_t *group;
@@ -4521,7 +4815,7 @@ _cairo_pdf_surface_mask (void *abstract_surface,
mask_status);
} else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
status = _cairo_pdf_surface_start_fallback (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4529,17 +4823,17 @@ _cairo_pdf_surface_mask (void *abstract_surface,
assert (_cairo_pdf_surface_operation_supported (surface, op, mask));
group = _cairo_pdf_surface_create_smask_group (surface);
- if (group == NULL)
+ if (unlikely (group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_MASK;
status = _cairo_pattern_create_copy (&group->source, source);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pattern_create_copy (&group->mask, mask);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
@@ -4550,21 +4844,21 @@ _cairo_pdf_surface_mask (void *abstract_surface,
}
status = _cairo_pdf_surface_add_smask_group (surface, group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, group->source_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4584,7 +4878,8 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
cairo_matrix_t *ctm,
cairo_matrix_t *ctm_inverse,
double tolerance,
- cairo_antialias_t antialias)
+ cairo_antialias_t antialias,
+ cairo_rectangle_int_t *extents)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_status_t status;
@@ -4598,26 +4893,27 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
pattern_res.id = 0;
gstate_res.id = 0;
- status = _cairo_pdf_surface_add_pdf_pattern (surface, source, &pattern_res, &gstate_res);
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents,
+ &pattern_res, &gstate_res);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
group = _cairo_pdf_surface_create_smask_group (surface);
- if (group == NULL)
+ if (unlikely (group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_STROKE;
status = _cairo_pattern_create_copy (&group->source, source);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
group->source_res = pattern_res;
status = _cairo_path_fixed_init_copy (&group->path, path);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
@@ -4626,21 +4922,21 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
group->ctm = *ctm;
group->ctm_inverse = *ctm_inverse;
status = _cairo_pdf_surface_add_smask_group (surface, group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4649,7 +4945,7 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, TRUE);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_stroke (&surface->pdf_operators,
@@ -4657,11 +4953,11 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
style,
ctm,
ctm_inverse);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4675,7 +4971,8 @@ _cairo_pdf_surface_fill (void *abstract_surface,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
- cairo_antialias_t antialias)
+ cairo_antialias_t antialias,
+ cairo_rectangle_int_t *extents)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_status_t status;
@@ -4686,7 +4983,7 @@ _cairo_pdf_surface_fill (void *abstract_surface,
return _cairo_pdf_surface_analyze_operation (surface, op, source);
} else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
status = _cairo_pdf_surface_start_fallback (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4694,47 +4991,48 @@ _cairo_pdf_surface_fill (void *abstract_surface,
pattern_res.id = 0;
gstate_res.id = 0;
- status = _cairo_pdf_surface_add_pdf_pattern (surface, source, &pattern_res, &gstate_res);
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents,
+ &pattern_res, &gstate_res);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
group = _cairo_pdf_surface_create_smask_group (surface);
- if (group == NULL)
+ if (unlikely (group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_FILL;
status = _cairo_pattern_create_copy (&group->source, source);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
group->source_res = pattern_res;
status = _cairo_path_fixed_init_copy (&group->path, path);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
group->fill_rule = fill_rule;
status = _cairo_pdf_surface_add_smask_group (surface, group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4743,17 +5041,17 @@ _cairo_pdf_surface_fill (void *abstract_surface,
group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_fill (&surface->pdf_operators,
path,
fill_rule);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4774,7 +5072,8 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
cairo_matrix_t *stroke_ctm,
cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
- cairo_antialias_t stroke_antialias)
+ cairo_antialias_t stroke_antialias,
+ cairo_rectangle_int_t *extents)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_status_t status;
@@ -4802,9 +5101,10 @@ _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,
+ extents,
&fill_pattern_res,
&gstate_res);
- if (status)
+ if (unlikely (status))
return status;
assert (gstate_res.id == 0);
@@ -4813,9 +5113,10 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
gstate_res.id = 0;
status = _cairo_pdf_surface_add_pdf_pattern (surface,
stroke_source,
+ extents,
&stroke_pattern_res,
&gstate_res);
- if (status)
+ if (unlikely (status))
return status;
assert (gstate_res.id == 0);
@@ -4824,12 +5125,12 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
* select both at the same time */
status = _cairo_pdf_surface_select_pattern (surface, fill_source,
fill_pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_select_pattern (surface, stroke_source,
stroke_pattern_res, TRUE);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_fill_stroke (&surface->pdf_operators,
@@ -4838,11 +5139,11 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
stroke_style,
stroke_ctm,
stroke_ctm_inverse);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
return _cairo_output_stream_get_status (surface->output);
@@ -4865,7 +5166,8 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
const cairo_text_cluster_t *clusters,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
- cairo_scaled_font_t *scaled_font)
+ cairo_scaled_font_t *scaled_font,
+ cairo_rectangle_int_t *extents)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_status_t status;
@@ -4879,20 +5181,21 @@ _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, &pattern_res, &gstate_res);
+ status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents,
+ &pattern_res, &gstate_res);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
- if (status)
+ if (unlikely (status))
return status;
if (gstate_res.id != 0) {
group = _cairo_pdf_surface_create_smask_group (surface);
- if (group == NULL)
+ if (unlikely (group == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_SHOW_GLYPHS;
status = _cairo_pattern_create_copy (&group->source, source);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
@@ -4900,7 +5203,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
if (utf8_len) {
group->utf8 = malloc (utf8_len);
- if (group->utf8 == NULL) {
+ if (unlikely (group->utf8 == NULL)) {
_cairo_pdf_smask_group_destroy (group);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -4910,7 +5213,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
if (num_glyphs) {
group->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
- if (group->glyphs == NULL) {
+ if (unlikely (group->glyphs == NULL)) {
_cairo_pdf_smask_group_destroy (group);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -4920,7 +5223,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
if (num_clusters) {
group->clusters = _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t));
- if (group->clusters == NULL) {
+ if (unlikely (group->clusters == NULL)) {
_cairo_pdf_smask_group_destroy (group);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -4930,21 +5233,21 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
group->scaled_font = cairo_scaled_font_reference (scaled_font);
status = _cairo_pdf_surface_add_smask_group (surface, group);
- if (status) {
+ if (unlikely (status)) {
_cairo_pdf_smask_group_destroy (group);
return status;
}
status = _cairo_pdf_surface_add_smask (surface, gstate_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
@@ -4953,7 +5256,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
group->group_res.id);
} else {
status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE);
- if (status)
+ if (unlikely (status))
return status;
/* Each call to show_glyphs() with a transclucent pattern must
@@ -4962,7 +5265,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
* each other. */
if (! _cairo_pattern_is_opaque (source)) {
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -4972,11 +5275,11 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
clusters, num_clusters,
cluster_flags,
scaled_font);
- if (status)
+ if (unlikely (status))
return status;
status = _cairo_pdf_surface_unselect_pattern (surface);
- if (status)
+ if (unlikely (status))
return status;
}
@@ -5005,6 +5308,8 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
+ NULL, /* create_span_renderer */
+ NULL, /* check_span_renderer */
NULL, /* _cairo_pdf_surface_copy_page */
_cairo_pdf_surface_show_page,
NULL, /* set_clip_region */