diff options
Diffstat (limited to 'src/cairo-pdf-surface.c')
-rw-r--r-- | src/cairo-pdf-surface.c | 723 |
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 */ |