[cairo-commit] 8 commits - src/cairo-pdf-surface.c src/cairo-pdf-surface-private.h src/cairo-ps-surface.c src/cairo-truetype-subset.c src/cairo-type1-subset.c
Adrian Johnson
ajohnson at kemper.freedesktop.org
Tue Dec 6 02:20:58 PST 2011
src/cairo-pdf-surface-private.h | 2
src/cairo-pdf-surface.c | 554 +++++++++++++++++++++++++++-------------
src/cairo-ps-surface.c | 85 ++++--
src/cairo-truetype-subset.c | 2
src/cairo-type1-subset.c | 8
5 files changed, 449 insertions(+), 202 deletions(-)
New commits:
commit a8cbb007844b04937b36cc387d5ad29b5fc70119
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Tue Dec 6 20:47:14 2011 +1030
pdf: avoid using pdf patterns to paint/fill translucent linear/radial gradients
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 5d3e3af..d7108d1 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -3238,11 +3238,27 @@ _cairo_pdf_surface_emit_repeating_function (cairo_pdf_surface_t *surface,
static cairo_status_t
cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
+ cairo_pdf_pattern_t *pdf_pattern,
cairo_pdf_resource_t gstate_resource,
cairo_pdf_resource_t gradient_mask)
{
cairo_pdf_resource_t smask_resource;
cairo_status_t status;
+ char buf[100];
+
+ if (pdf_pattern->is_shading) {
+ snprintf(buf, sizeof(buf),
+ " /Shading\n"
+ " << /sh%d %d 0 R >>\n",
+ gradient_mask.id,
+ gradient_mask.id);
+ } else {
+ snprintf(buf, sizeof(buf),
+ " /Pattern\n"
+ " << /p%d %d 0 R >>\n",
+ gradient_mask.id,
+ gradient_mask.id);
+ }
status = _cairo_pdf_surface_open_stream (surface,
NULL,
@@ -3255,8 +3271,7 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
" << /ExtGState\n"
" << /a0 << /ca 1 /CA 1 >>"
" >>\n"
- " /Pattern\n"
- " << /p%d %d 0 R >>\n"
+ "%s"
" >>\n"
" /Group\n"
" << /Type /Group\n"
@@ -3265,24 +3280,29 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
" >>\n",
surface->width,
surface->height,
- gradient_mask.id,
- gradient_mask.id);
+ buf);
if (unlikely (status))
return status;
- _cairo_output_stream_printf (surface->output,
- "q\n"
- "/a0 gs\n"
- "/Pattern cs /p%d scn\n"
- "0 0 %f %f re\n"
- "f\n"
- "Q\n",
- gradient_mask.id,
- surface->width,
- surface->height);
-
- status = _cairo_pdf_surface_close_stream (surface);
- if (unlikely (status))
+ if (pdf_pattern->is_shading) {
+ _cairo_output_stream_printf (surface->output,
+ "/a0 gs /sh%d sh\n",
+ gradient_mask.id);
+ } else {
+ _cairo_output_stream_printf (surface->output,
+ "q\n"
+ "/a0 gs\n"
+ "/Pattern cs /p%d scn\n"
+ "0 0 %f %f re\n"
+ "f\n"
+ "Q\n",
+ gradient_mask.id,
+ surface->width,
+ surface->height);
+ }
+
+ status = _cairo_pdf_surface_close_stream (surface);
+ if (unlikely (status))
return status;
smask_resource = _cairo_pdf_surface_new_object (surface);
@@ -3522,11 +3542,8 @@ _cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t *surface,
&pat_to_pdf, &start, &end, domain,
"/DeviceGray", alpha_function);
- status = _cairo_pdf_surface_add_pattern (surface, mask_resource);
- if (unlikely (status))
- return status;
-
status = cairo_pdf_surface_emit_transparency_group (surface,
+ pdf_pattern,
pdf_pattern->gstate_res,
mask_resource);
if (unlikely (status))
@@ -3671,6 +3688,7 @@ _cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t *surface,
res.id);
status = cairo_pdf_surface_emit_transparency_group (surface,
+ pdf_pattern,
pdf_pattern->gstate_res,
mask_resource);
if (unlikely (status))
@@ -3825,8 +3843,6 @@ _cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t *surface,
if (unlikely (status))
return status;
- assert (gstate_res.id == 0);
-
pat_to_pdf = source->matrix;
status = cairo_matrix_invert (&pat_to_pdf);
/* cairo_pattern_set_matrix ensures the matrix is invertible */
@@ -3845,19 +3861,29 @@ _cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t *surface,
pat_to_pdf.x0, pat_to_pdf.y0);
}
- status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
- if (unlikely (status))
- return status;
-
status = _cairo_pdf_surface_add_shading (surface, shading_res);
if (unlikely (status))
return status;
+ if (gstate_res.id != 0) {
+ status = _cairo_pdf_surface_add_smask (surface, gstate_res);
+ if (unlikely (status))
+ return status;
- _cairo_output_stream_printf (surface->output,
- "/a%d gs /sh%d sh\n",
- alpha,
- shading_res.id);
+ _cairo_output_stream_printf (surface->output,
+ "/s%d gs /sh%d sh\n",
+ gstate_res.id,
+ shading_res.id);
+ } else {
+ status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
+ if (unlikely (status))
+ return status;
+
+ _cairo_output_stream_printf (surface->output,
+ "/a%d gs /sh%d sh\n",
+ alpha,
+ shading_res.id);
+ }
return status;
}
@@ -3891,8 +3917,6 @@ _cairo_pdf_surface_paint_pattern (cairo_pdf_surface_t *surface,
static cairo_bool_t
_can_paint_pattern (const cairo_pattern_t *pattern)
{
- double min_alpha;
-
switch (pattern->type) {
case CAIRO_PATTERN_TYPE_SOLID:
return FALSE;
@@ -3903,8 +3927,7 @@ _can_paint_pattern (const cairo_pattern_t *pattern)
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL:
- _cairo_pattern_alpha_range (pattern, &min_alpha, NULL);
- return CAIRO_ALPHA_IS_OPAQUE (min_alpha);
+ return TRUE;
case CAIRO_PATTERN_TYPE_MESH:
return FALSE;
commit 79f430e7ada4384390dc03caab2af0ffc1603885
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Tue Dec 6 20:46:49 2011 +1030
pdf: avoid using pdf patterns to paint/fill opaque linear/radial gradients
Patterns are slower and use more memory to print. For painting and
filling we can use the shading operator to draw gradients.
diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h
index 08620e6..1e174fe 100644
--- a/src/cairo-pdf-surface-private.h
+++ b/src/cairo-pdf-surface-private.h
@@ -60,6 +60,7 @@ typedef struct _cairo_pdf_group_resources {
cairo_array_t alphas;
cairo_array_t smasks;
cairo_array_t patterns;
+ cairo_array_t shadings;
cairo_array_t xobjects;
cairo_array_t fonts;
} cairo_pdf_group_resources_t;
@@ -89,6 +90,7 @@ typedef struct _cairo_pdf_pattern {
cairo_pattern_t *pattern;
cairo_pdf_resource_t pattern_res;
cairo_pdf_resource_t gstate_res;
+ cairo_bool_t is_shading;
} cairo_pdf_pattern_t;
typedef enum _cairo_pdf_operation {
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index f61638c..5d3e3af 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -715,6 +715,7 @@ _cairo_pdf_group_resources_init (cairo_pdf_group_resources_t *res)
_cairo_array_init (&res->alphas, sizeof (double));
_cairo_array_init (&res->smasks, sizeof (cairo_pdf_resource_t));
_cairo_array_init (&res->patterns, sizeof (cairo_pdf_resource_t));
+ _cairo_array_init (&res->shadings, sizeof (cairo_pdf_resource_t));
_cairo_array_init (&res->xobjects, sizeof (cairo_pdf_resource_t));
_cairo_array_init (&res->fonts, sizeof (cairo_pdf_font_t));
}
@@ -725,6 +726,7 @@ _cairo_pdf_group_resources_fini (cairo_pdf_group_resources_t *res)
_cairo_array_fini (&res->alphas);
_cairo_array_fini (&res->smasks);
_cairo_array_fini (&res->patterns);
+ _cairo_array_fini (&res->shadings);
_cairo_array_fini (&res->xobjects);
_cairo_array_fini (&res->fonts);
}
@@ -740,6 +742,7 @@ _cairo_pdf_group_resources_clear (cairo_pdf_group_resources_t *res)
_cairo_array_truncate (&res->alphas, 0);
_cairo_array_truncate (&res->smasks, 0);
_cairo_array_truncate (&res->patterns, 0);
+ _cairo_array_truncate (&res->shadings, 0);
_cairo_array_truncate (&res->xobjects, 0);
_cairo_array_truncate (&res->fonts, 0);
}
@@ -796,6 +799,14 @@ _cairo_pdf_surface_add_pattern (cairo_pdf_surface_t *surface,
}
static cairo_status_t
+_cairo_pdf_surface_add_shading (cairo_pdf_surface_t *surface,
+ cairo_pdf_resource_t shading)
+{
+ return _cairo_array_append (&(surface->resources.shadings), &shading);
+}
+
+
+static cairo_status_t
_cairo_pdf_surface_add_xobject (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t xobject)
{
@@ -908,7 +919,7 @@ _cairo_pdf_surface_emit_group_resources (cairo_pdf_surface_t *surface,
{
int num_alphas, num_smasks, num_resources, i;
double alpha;
- cairo_pdf_resource_t *smask, *pattern, *xobject;
+ cairo_pdf_resource_t *smask, *pattern, *shading, *xobject;
cairo_pdf_font_t *font;
_cairo_output_stream_printf (surface->output, "<<\n");
@@ -960,6 +971,21 @@ _cairo_pdf_surface_emit_group_resources (cairo_pdf_surface_t *surface,
" >>\n");
}
+ num_resources = _cairo_array_num_elements (&res->shadings);
+ if (num_resources > 0) {
+ _cairo_output_stream_printf (surface->output,
+ " /Shading <<");
+ for (i = 0; i < num_resources; i++) {
+ shading = _cairo_array_index (&res->shadings, i);
+ _cairo_output_stream_printf (surface->output,
+ " /sh%d %d 0 R",
+ shading->id, shading->id);
+ }
+
+ _cairo_output_stream_printf (surface->output,
+ " >>\n");
+ }
+
num_resources = _cairo_array_num_elements (&res->xobjects);
if (num_resources > 0) {
_cairo_output_stream_printf (surface->output,
@@ -1282,15 +1308,18 @@ _cairo_pdf_surface_add_source_surface (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,
- const cairo_rectangle_int_t *extents,
- cairo_pdf_resource_t *pattern_res,
- cairo_pdf_resource_t *gstate_res)
+_cairo_pdf_surface_add_pdf_pattern_or_shading (cairo_pdf_surface_t *surface,
+ const cairo_pattern_t *pattern,
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t is_shading,
+ cairo_pdf_resource_t *pattern_res,
+ cairo_pdf_resource_t *gstate_res)
{
cairo_pdf_pattern_t pdf_pattern;
cairo_status_t status;
+ pdf_pattern.is_shading = is_shading;
+
/* Solid colors are emitted into the content stream */
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
pattern_res->id = 0;
@@ -1363,6 +1392,36 @@ _get_bbox_from_extents (double surface_height,
}
static cairo_status_t
+_cairo_pdf_surface_add_pdf_shading (cairo_pdf_surface_t *surface,
+ const cairo_pattern_t *pattern,
+ const cairo_rectangle_int_t *extents,
+ cairo_pdf_resource_t *shading_res,
+ cairo_pdf_resource_t *gstate_res)
+{
+ return _cairo_pdf_surface_add_pdf_pattern_or_shading (surface,
+ pattern,
+ extents,
+ TRUE,
+ shading_res,
+ gstate_res);
+}
+
+static cairo_status_t
+_cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
+ const cairo_pattern_t *pattern,
+ const cairo_rectangle_int_t *extents,
+ cairo_pdf_resource_t *pattern_res,
+ cairo_pdf_resource_t *gstate_res)
+{
+ return _cairo_pdf_surface_add_pdf_pattern_or_shading (surface,
+ pattern,
+ extents,
+ FALSE,
+ pattern_res,
+ gstate_res);
+}
+
+static cairo_status_t
_cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t *resource,
cairo_bool_t compressed,
@@ -3270,15 +3329,19 @@ _cairo_pdf_surface_output_gradient (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t color_function)
{
_cairo_output_stream_printf (surface->output,
- "%d 0 obj\n"
- "<< /Type /Pattern\n"
- " /PatternType 2\n"
- " /Matrix [ %f %f %f %f %f %f ]\n"
- " /Shading\n",
- pattern_resource.id,
- pat_to_pdf->xx, pat_to_pdf->yx,
- pat_to_pdf->xy, pat_to_pdf->yy,
- pat_to_pdf->x0, pat_to_pdf->y0);
+ "%d 0 obj\n",
+ pattern_resource.id);
+
+ if (!pdf_pattern->is_shading) {
+ _cairo_output_stream_printf (surface->output,
+ "<< /Type /Pattern\n"
+ " /PatternType 2\n"
+ " /Matrix [ %f %f %f %f %f %f ]\n"
+ " /Shading\n",
+ pat_to_pdf->xx, pat_to_pdf->yx,
+ pat_to_pdf->xy, pat_to_pdf->yy,
+ pat_to_pdf->x0, pat_to_pdf->y0);
+ }
if (pdf_pattern->pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
_cairo_output_stream_printf (surface->output,
@@ -3314,10 +3377,14 @@ _cairo_pdf_surface_output_gradient (cairo_pdf_surface_t *surface,
_cairo_output_stream_printf (surface->output,
" /Function %d 0 R\n"
- " >>\n"
- ">>\n"
- "endobj\n",
+ " >>\n",
color_function.id);
+
+ if (!pdf_pattern->is_shading) {
+ _cairo_output_stream_printf (surface->output,
+ ">>\n"
+ "endobj\n");
+ }
}
static cairo_status_t
@@ -3741,6 +3808,114 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
}
static cairo_status_t
+_cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t *surface,
+ const cairo_pattern_t *source,
+ const cairo_rectangle_int_t *extents)
+{
+ cairo_pdf_resource_t shading_res, gstate_res;
+ cairo_matrix_t pat_to_pdf;
+ cairo_status_t status;
+ int alpha;
+
+ status = _cairo_pdf_surface_add_pdf_shading (surface, source,
+ extents,
+ &shading_res, &gstate_res);
+ if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
+ return CAIRO_STATUS_SUCCESS;
+ if (unlikely (status))
+ return status;
+
+ assert (gstate_res.id == 0);
+
+ pat_to_pdf = source->matrix;
+ status = cairo_matrix_invert (&pat_to_pdf);
+ /* cairo_pattern_set_matrix ensures the matrix is invertible */
+ assert (status == CAIRO_STATUS_SUCCESS);
+ cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
+
+ status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+ if (unlikely (status))
+ return status;
+
+ if (! _cairo_matrix_is_identity (&pat_to_pdf)) {
+ _cairo_output_stream_printf (surface->output,
+ "%f %f %f %f %f %f cm\n",
+ pat_to_pdf.xx, pat_to_pdf.yx,
+ pat_to_pdf.xy, pat_to_pdf.yy,
+ pat_to_pdf.x0, pat_to_pdf.y0);
+ }
+
+ status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_pdf_surface_add_shading (surface, shading_res);
+ if (unlikely (status))
+ return status;
+
+
+ _cairo_output_stream_printf (surface->output,
+ "/a%d gs /sh%d sh\n",
+ alpha,
+ shading_res.id);
+
+ return status;
+}
+
+static cairo_status_t
+_cairo_pdf_surface_paint_pattern (cairo_pdf_surface_t *surface,
+ const cairo_pattern_t *source,
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t mask)
+{
+ switch (source->type) {
+ case CAIRO_PATTERN_TYPE_SURFACE:
+ return _cairo_pdf_surface_paint_surface_pattern (surface,
+ (cairo_surface_pattern_t *)source,
+ extents,
+ mask);
+ case CAIRO_PATTERN_TYPE_LINEAR:
+ case CAIRO_PATTERN_TYPE_RADIAL:
+ case CAIRO_PATTERN_TYPE_MESH:
+ return _cairo_pdf_surface_paint_gradient (surface,
+ source,
+ extents);
+
+ case CAIRO_PATTERN_TYPE_SOLID:
+ default:
+ ASSERT_NOT_REACHED;
+ return CAIRO_STATUS_SUCCESS;
+ }
+}
+
+static cairo_bool_t
+_can_paint_pattern (const cairo_pattern_t *pattern)
+{
+ double min_alpha;
+
+ switch (pattern->type) {
+ case CAIRO_PATTERN_TYPE_SOLID:
+ return FALSE;
+
+ case CAIRO_PATTERN_TYPE_SURFACE:
+ return (pattern->extend == CAIRO_EXTEND_NONE ||
+ pattern->extend == CAIRO_EXTEND_PAD);
+
+ case CAIRO_PATTERN_TYPE_LINEAR:
+ case CAIRO_PATTERN_TYPE_RADIAL:
+ _cairo_pattern_alpha_range (pattern, &min_alpha, NULL);
+ return CAIRO_ALPHA_IS_OPAQUE (min_alpha);
+
+ case CAIRO_PATTERN_TYPE_MESH:
+ return FALSE;
+
+ default:
+ ASSERT_NOT_REACHED;
+ return FALSE;
+ }
+}
+
+static cairo_status_t
_cairo_pdf_surface_select_operator (cairo_pdf_surface_t *surface,
cairo_operator_t op)
{
@@ -6041,15 +6216,12 @@ _cairo_pdf_surface_paint (void *abstract_surface,
if (unlikely (status))
goto cleanup;
- if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
- (source->extend == CAIRO_EXTEND_NONE ||
- source->extend == CAIRO_EXTEND_PAD))
- {
+ if (_can_paint_pattern (source)) {
_cairo_output_stream_printf (surface->output, "q\n");
- status = _cairo_pdf_surface_paint_surface_pattern (surface,
- (cairo_surface_pattern_t *) source,
- &extents.bounded,
- FALSE);
+ status = _cairo_pdf_surface_paint_pattern (surface,
+ source,
+ &extents.bounded,
+ FALSE);
if (unlikely (status))
goto cleanup;
@@ -6458,10 +6630,7 @@ _cairo_pdf_surface_fill (void *abstract_surface,
if (unlikely (status))
goto cleanup;
- if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
- (source->extend == CAIRO_EXTEND_NONE ||
- source->extend == CAIRO_EXTEND_PAD))
- {
+ if (_can_paint_pattern (source)) {
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
if (unlikely (status))
goto cleanup;
@@ -6473,10 +6642,10 @@ _cairo_pdf_surface_fill (void *abstract_surface,
if (unlikely (status))
goto cleanup;
- status = _cairo_pdf_surface_paint_surface_pattern (surface,
- (cairo_surface_pattern_t *) source,
- &extents.bounded,
- FALSE);
+ status = _cairo_pdf_surface_paint_pattern (surface,
+ source,
+ &extents.bounded,
+ FALSE);
if (unlikely (status))
goto cleanup;
commit dee48f0dcadf96e88872894a1cef280905cd255f
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Tue Dec 6 20:46:35 2011 +1030
ps: allow embedding of cmyk jpeg images
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index def9e62..f206adc 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -2511,6 +2511,8 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
const unsigned char *mime_data;
unsigned long mime_data_length;
cairo_image_info_t info;
+ const char *colorspace;
+ const char *decode;
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
&mime_data, &mime_data_length);
@@ -2523,8 +2525,22 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
if (unlikely (status))
return status;
- if (info.num_components != 1 && info.num_components != 3)
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ switch (info.num_components) {
+ case 1:
+ colorspace = "/DeviceGray";
+ decode = "0 1";
+ break;
+ case 3:
+ colorspace = "/DeviceRGB";
+ decode = "0 1 0 1 0 1";
+ break;
+ case 4:
+ colorspace = "/DeviceCMYK";
+ decode = "0 1 0 1 0 1 0 1";
+ break;
+ default:
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
if (surface->use_string_datasource) {
/* Emit the image data as a base85-encoded string which will
@@ -2547,18 +2563,18 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
}
_cairo_output_stream_printf (surface->stream,
- "/%s setcolorspace\n"
+ "%s setcolorspace\n"
"8 dict dup begin\n"
" /ImageType 1 def\n"
" /Width %d def\n"
" /Height %d def\n"
" /BitsPerComponent %d def\n"
" /Decode [ %s ] def\n",
- info.num_components == 1 ? "DeviceGray" : "DeviceRGB",
+ colorspace,
info.width,
info.height,
info.bits_per_component,
- info.num_components == 1 ? "0 1" : "0 1 0 1 0 1");
+ decode);
if (surface->use_string_datasource) {
_cairo_output_stream_printf (surface->stream,
commit 74c0a06105e3d08b057a770e0545849836f6babb
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Tue Dec 6 20:46:21 2011 +1030
pdf: allow embedding of cmyk jpeg images
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 5a54530..f61638c 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -2330,6 +2330,7 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
const unsigned char *mime_data;
unsigned long mime_data_length;
cairo_image_info_t info;
+ const char *colorspace;
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
&mime_data, &mime_data_length);
@@ -2342,8 +2343,19 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
if (unlikely (status))
return status;
- if (info.num_components != 1 && info.num_components != 3)
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ switch (info.num_components) {
+ case 1:
+ colorspace = "/DeviceGray";
+ break;
+ case 3:
+ colorspace = "/DeviceRGB";
+ break;
+ case 4:
+ colorspace = "/DeviceCMYK";
+ break;
+ default:
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
status = _cairo_pdf_surface_open_stream (surface,
&res,
@@ -2357,7 +2369,7 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
" /Filter /DCTDecode\n",
info.width,
info.height,
- info.num_components == 1 ? "/DeviceGray" : "/DeviceRGB",
+ colorspace,
info.bits_per_component);
if (unlikely (status))
return status;
commit 25e35b46bfd2a71a8cf0484e51351961ad1c82a3
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Tue Dec 6 20:45:31 2011 +1030
ps: avoid padding images if the padding is not required to fill the extents
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 95b3d12..def9e62 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -2820,6 +2820,7 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface,
cairo_surface_t *pad_image;
int x = 0;
int y = 0;
+ int w, h;
surface->acquired_image = NULL;
surface->image = NULL;
@@ -2866,32 +2867,42 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface,
_cairo_box_from_rectangle (&box, 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_pixman_format (NULL,
- surface->acquired_image->pixman_format,
- rect.width, rect.height,
- 0);
- if (pad_image->status) {
- status = pad_image->status;
- goto BAIL;
- }
- _cairo_pattern_init_for_surface (&pad_pattern, &surface->acquired_image->base);
- cairo_matrix_init_translate (&pad_pattern.base.matrix, -x, -y);
- pad_pattern.base.extend = CAIRO_EXTEND_PAD;
- status = _cairo_surface_paint (pad_image,
- CAIRO_OPERATOR_SOURCE,
- &pad_pattern.base,
- NULL);
- _cairo_pattern_fini (&pad_pattern.base);
- if (unlikely (status)) {
- if (pad_image != &surface->acquired_image->base)
- cairo_surface_destroy (pad_image);
+ /* Check if image needs padding to fill extents. */
+ w = surface->acquired_image->width;
+ h = surface->acquired_image->height;
+ if (_cairo_fixed_integer_ceil(box.p1.x) < 0 ||
+ _cairo_fixed_integer_ceil(box.p1.y) < 0 ||
+ _cairo_fixed_integer_floor(box.p2.y) > w ||
+ _cairo_fixed_integer_floor(box.p2.y) > h)
+ {
+ x = -rect.x;
+ y = -rect.y;
+
+ pad_image =
+ _cairo_image_surface_create_with_pixman_format (NULL,
+ surface->acquired_image->pixman_format,
+ rect.width, rect.height,
+ 0);
+ if (pad_image->status) {
+ status = pad_image->status;
+ goto BAIL;
+ }
- goto BAIL;
+ _cairo_pattern_init_for_surface (&pad_pattern, &surface->acquired_image->base);
+ cairo_matrix_init_translate (&pad_pattern.base.matrix, -x, -y);
+ pad_pattern.base.extend = CAIRO_EXTEND_PAD;
+ status = _cairo_surface_paint (pad_image,
+ CAIRO_OPERATOR_SOURCE,
+ &pad_pattern.base,
+ NULL);
+ _cairo_pattern_fini (&pad_pattern.base);
+ if (unlikely (status)) {
+ if (pad_image != &surface->acquired_image->base)
+ cairo_surface_destroy (pad_image);
+
+ goto BAIL;
+ }
}
}
commit c7ce1b68d5370f6e804a6edbf5be4bca3a5b7c57
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Tue Dec 6 20:45:14 2011 +1030
pdf: don't use patterns with padded images
and avoid padding if the padding is not required to fill the extents.
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index f45846c..5a54530 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1875,6 +1875,93 @@ _cairo_pdf_surface_supports_fine_grained_fallbacks (void *abstract_surface)
return TRUE;
}
+static cairo_status_t
+_cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t *surface,
+ cairo_surface_pattern_t *source,
+ const cairo_rectangle_int_t *extents,
+ cairo_pdf_resource_t *surface_res,
+ int *width,
+ int *height,
+ int *origin_x,
+ int *origin_y)
+{
+ cairo_image_surface_t *image;
+ cairo_surface_t *pad_image;
+ void *image_extra;
+ cairo_int_status_t status;
+ int x = 0;
+ int y = 0;
+ int w, h;
+ cairo_rectangle_int_t extents2;
+ cairo_box_t box;
+ cairo_rectangle_int_t rect;
+ cairo_surface_pattern_t pad_pattern;
+
+ status = _cairo_surface_acquire_source_image (source->surface, &image, &image_extra);
+ if (unlikely (status))
+ return status;
+
+ pad_image = &image->base;
+
+ /* get the operation extents in pattern space */
+ _cairo_box_from_rectangle (&box, extents);
+ _cairo_matrix_transform_bounding_box_fixed (&source->base.matrix, &box, NULL);
+ _cairo_box_round_to_rectangle (&box, &rect);
+
+ /* Check if image needs padding to fill extents */
+ w = image->width;
+ h = image->height;
+ if (_cairo_fixed_integer_ceil(box.p1.x) < 0 ||
+ _cairo_fixed_integer_ceil(box.p1.y) < 0 ||
+ _cairo_fixed_integer_floor(box.p2.y) > w ||
+ _cairo_fixed_integer_floor(box.p2.y) > h)
+ {
+ x = -rect.x;
+ y = -rect.y;
+ pad_image = _cairo_image_surface_create_with_content (source->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_paint (pad_image,
+ CAIRO_OPERATOR_SOURCE, &pad_pattern.base,
+ NULL);
+ _cairo_pattern_fini (&pad_pattern.base);
+ if (unlikely (status))
+ goto BAIL;
+ }
+
+ status = _cairo_pdf_surface_add_source_surface (surface,
+ pad_image,
+ source->base.filter,
+ FALSE,
+ surface_res,
+ &w,
+ &h,
+ &extents2);
+ if (unlikely (status))
+ goto BAIL;
+
+ *width = ((cairo_image_surface_t *)pad_image)->width;
+ *height = ((cairo_image_surface_t *)pad_image)->height;
+ *origin_x = x;
+ *origin_y = y;
+
+BAIL:
+ if (pad_image != &image->base)
+ cairo_surface_destroy (pad_image);
+
+ _cairo_surface_release_source_image (source->surface, image, image_extra);
+
+ return status;
+}
+
/* Emit alpha channel from the image into the given data, providing
* an id that can be used to reference the resulting SMask object.
*
@@ -2318,100 +2405,6 @@ BAIL:
}
static cairo_status_t
-_cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t *surface,
- cairo_pdf_pattern_t *pdf_pattern,
- cairo_pdf_resource_t *resource,
- int *width,
- int *height,
- int *origin_x,
- int *origin_y)
-{
- cairo_image_surface_t *image;
- cairo_surface_t *pad_image;
- void *image_extra;
- cairo_int_status_t status;
- cairo_surface_pattern_t *pattern = (cairo_surface_pattern_t *) pdf_pattern->pattern;
- int x = 0;
- int y = 0;
- cairo_bool_t interpolate;
-
- status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
- if (unlikely (status))
- return status;
-
- pad_image = &image->base;
- if (pattern->base.extend == 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_paint (pad_image,
- CAIRO_OPERATOR_SOURCE, &pad_pattern.base,
- NULL);
- _cairo_pattern_fini (&pad_pattern.base);
- if (unlikely (status))
- goto BAIL;
- }
-
- switch (pdf_pattern->pattern->filter) {
- default:
- case CAIRO_FILTER_GOOD:
- case CAIRO_FILTER_BEST:
- case CAIRO_FILTER_BILINEAR:
- interpolate = TRUE;
- break;
- case CAIRO_FILTER_FAST:
- case CAIRO_FILTER_NEAREST:
- case CAIRO_FILTER_GAUSSIAN:
- interpolate = FALSE;
- break;
- }
-
- *resource = _cairo_pdf_surface_new_object (surface);
- if (resource->id == 0) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
- goto BAIL;
- }
-
- status = _cairo_pdf_surface_emit_image (surface, (cairo_image_surface_t *)pad_image,
- resource, interpolate, FALSE);
- if (unlikely (status))
- goto BAIL;
-
- *width = ((cairo_image_surface_t *)pad_image)->width;
- *height = ((cairo_image_surface_t *)pad_image)->height;
- *origin_x = x;
- *origin_y = y;
-
-BAIL:
- if (pad_image != &image->base)
- cairo_surface_destroy (pad_image);
-
- _cairo_surface_release_source_image (pattern->surface, image, image_extra);
-
- return status;
-}
-
-
-static cairo_status_t
_cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
cairo_pdf_source_surface_t *pdf_source)
{
@@ -2590,13 +2583,14 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
if (pattern->base.extend == CAIRO_EXTEND_PAD &&
pattern->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
{
- status = _cairo_pdf_surface_emit_padded_image_surface (surface,
- pdf_pattern,
- &pattern_resource,
- &pattern_width,
- &pattern_height,
- &origin_x,
- &origin_y);
+ status = _cairo_pdf_surface_add_padded_image_surface (surface,
+ pattern,
+ &pdf_pattern->extents,
+ &pattern_resource,
+ &pattern_width,
+ &pattern_height,
+ &origin_x,
+ &origin_y);
pattern_extents.x = 0;
pattern_extents.y = 0;
pattern_extents.width = pattern_width;
@@ -3653,25 +3647,41 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern
}
static cairo_status_t
-_cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
- cairo_surface_pattern_t *source,
- cairo_bool_t stencil_mask)
+_cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
+ cairo_surface_pattern_t *source,
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t stencil_mask)
{
cairo_pdf_resource_t surface_res;
int width, height;
cairo_matrix_t cairo_p2d, pdf_p2d;
cairo_status_t status;
int alpha;
- cairo_rectangle_int_t extents;
+ cairo_rectangle_int_t extents2;
+ int origin_x = 0;
+ int origin_y = 0;
- status = _cairo_pdf_surface_add_source_surface (surface,
- source->surface,
- source->base.filter,
- stencil_mask,
- &surface_res,
- &width,
- &height,
- &extents);
+ if (source->base.extend == CAIRO_EXTEND_PAD &&
+ source->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
+ {
+ status = _cairo_pdf_surface_add_padded_image_surface (surface,
+ source,
+ extents,
+ &surface_res,
+ &width,
+ &height,
+ &origin_x,
+ &origin_y);
+ } else {
+ status = _cairo_pdf_surface_add_source_surface (surface,
+ source->surface,
+ source->base.filter,
+ stencil_mask,
+ &surface_res,
+ &width,
+ &height,
+ &extents2);
+ }
if (unlikely (status))
return status;
@@ -3682,6 +3692,7 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
pdf_p2d = surface->cairo_to_pdf;
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, height);
cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
if (source->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
@@ -5943,6 +5954,7 @@ _cairo_pdf_surface_emit_stencil_mask (cairo_pdf_surface_t *surface,
_cairo_output_stream_printf (surface->output, "q\n");
status = _cairo_pdf_surface_paint_surface_pattern (surface,
(cairo_surface_pattern_t *) surface_pattern,
+ NULL,
TRUE);
if (unlikely (status))
return status;
@@ -6018,11 +6030,13 @@ _cairo_pdf_surface_paint (void *abstract_surface,
goto cleanup;
if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
- source->extend == CAIRO_EXTEND_NONE)
+ (source->extend == CAIRO_EXTEND_NONE ||
+ source->extend == CAIRO_EXTEND_PAD))
{
_cairo_output_stream_printf (surface->output, "q\n");
status = _cairo_pdf_surface_paint_surface_pattern (surface,
(cairo_surface_pattern_t *) source,
+ &extents.bounded,
FALSE);
if (unlikely (status))
goto cleanup;
@@ -6433,7 +6447,8 @@ _cairo_pdf_surface_fill (void *abstract_surface,
goto cleanup;
if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
- source->extend == CAIRO_EXTEND_NONE)
+ (source->extend == CAIRO_EXTEND_NONE ||
+ source->extend == CAIRO_EXTEND_PAD))
{
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
if (unlikely (status))
@@ -6448,6 +6463,7 @@ _cairo_pdf_surface_fill (void *abstract_surface,
status = _cairo_pdf_surface_paint_surface_pattern (surface,
(cairo_surface_pattern_t *) source,
+ &extents.bounded,
FALSE);
if (unlikely (status))
goto cleanup;
commit 346b8fe3984acd2127285f4a57516a3deda5df25
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Tue Dec 6 20:44:50 2011 +1030
type1-subset: remove unused variables
diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index efe3028..e12d1c2 100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -1094,7 +1094,7 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
const char *p, *subrs, *charstrings, *array_start, *array_end, *dict_start, *dict_end;
const char *closefile_token;
char buffer[32], *subr_count_end, *glyph_count_end;
- int num_charstrings, length;
+ int length;
const cairo_scaled_font_backend_t *backend;
unsigned int i;
@@ -1160,7 +1160,7 @@ skip_subrs:
/* Scan past /CharStrings and the integer following it. */
p = charstrings + strlen ("/CharStrings");
- num_charstrings = strtol (p, &glyph_count_end, 10);
+ strtol (p, &glyph_count_end, 10);
if (p == glyph_count_end)
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1513,7 +1513,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
cairo_bool_t hex_encode)
{
cairo_type1_font_subset_t font;
- cairo_status_t status, status_ignored;
+ cairo_status_t status;
unsigned long length;
unsigned int i;
char buf[30];
@@ -1579,7 +1579,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
fail2:
free (type1_subset->base_font);
fail1:
- status_ignored = _cairo_type1_font_subset_fini (&font);
+ _cairo_type1_font_subset_fini (&font);
return status;
}
commit ed7157d705ba9bfe3cc95f1e7b0ea11a91df7fa3
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Tue Dec 6 20:44:22 2011 +1030
truetype-subset: remove unused variable
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 1afdf3a..18ee685 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -1250,7 +1250,6 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
uint16_t *end_code;
uint16_t *delta;
uint16_t *range_offset;
- uint16_t *glyph_array;
uint16_t c;
backend = scaled_font->backend;
@@ -1290,7 +1289,6 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
start_code = &(end_code[num_segments + 1]);
delta = &(start_code[num_segments]);
range_offset = &(delta[num_segments]);
- glyph_array = &(range_offset[num_segments]);
/* search for glyph in segments with rangeOffset=0 */
for (i = 0; i < num_segments; i++) {
More information about the cairo-commit
mailing list