[cairo] Strange problem with PDF generation
Adrian Johnson
ajohnson at redneon.com
Thu Feb 1 06:01:34 PST 2007
Umberto Allievi wrote:
> The generated pdf looks good when viewed in both evince and acrobat
> reader, but when printed (even with cups-PDF) it ...
> - looks weird if printed with acrobat reader
> - evince outputs a blank sheet
> If I generate a PS file everything is OK.
The attached patch seems to correct this problem. I am interested
in getting feedback on how well the it works. Note that the patch in its
present form breaks non TrueType fonts. I will fix this once I am
certain this patch fixes the PDF TrueType printing problem.
This patch contains two changes:
- Include glyph 0 (.notdef) in the subset and map character 0 to notdef.
- Include an Encoding dictionary in the PDF TrueType subset.
-------------- next part --------------
>From 305ef4d85fd1e673b4574ce2345debd6afc7fd19 Mon Sep 17 00:00:00 2001
From: asj <asj at tux.lan>
Date: Thu, 1 Feb 2007 23:46:20 +1030
Subject: [PATCH] Truetype Subsetting: Include .notdef and add Encoding to PDF
---
src/cairo-pdf-surface.c | 29 +++++++++++++++++++++++------
src/cairo-ps-surface.c | 10 +++++-----
src/cairo-truetype-subset.c | 3 ++-
3 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index bdfef00..7db4a6c 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -138,7 +138,7 @@ typedef struct _cairo_pdf_surface {
cairo_paginated_mode_t paginated_mode;
} cairo_pdf_surface_t;
-#define PDF_SURFACE_MAX_GLYPHS_PER_FONT 256
+#define PDF_SURFACE_MAX_GLYPHS_PER_FONT 255
static cairo_pdf_resource_t
_cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface);
@@ -1876,7 +1876,7 @@ static cairo_status_t
_cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
cairo_scaled_font_subset_t *font_subset)
{
- cairo_pdf_resource_t stream, descriptor, subset_resource;
+ cairo_pdf_resource_t stream, encoding, descriptor, subset_resource;
cairo_status_t status;
cairo_pdf_font_t font;
cairo_truetype_subset_t subset;
@@ -1913,11 +1913,26 @@ _cairo_pdf_surface_emit_truetype_font_su
"endobj\r\n");
free (compressed);
+ encoding = _cairo_pdf_surface_new_object (surface);
+ _cairo_output_stream_printf (surface->output,
+ "%d 0 obj\r\n"
+ "<< /Type /Encoding\r\n"
+ " /Differences [0 /.notdef ",
+ encoding.id);
+
+ for (i = 0; i < font_subset->num_glyphs; i++)
+ _cairo_output_stream_printf (surface->output, "/g%d ", i + 1);
+
+ _cairo_output_stream_printf (surface->output,
+ " ]\r\n"
+ ">>\r\n"
+ "endobj\r\n");
+
descriptor = _cairo_pdf_surface_new_object (surface);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\r\n"
"<< /Type /FontDescriptor\r\n"
- " /FontName /7%s\r\n"
+ " /FontName /%s\r\n"
" /Flags 4\r\n"
" /FontBBox [ %ld %ld %ld %ld ]\r\n"
" /ItalicAngle 0\r\n"
@@ -1948,11 +1963,13 @@ _cairo_pdf_surface_emit_truetype_font_su
" /FirstChar 0\r\n"
" /LastChar %d\r\n"
" /FontDescriptor %d 0 R\r\n"
+ " /Encoding %d 0 R\r\n"
" /Widths [",
subset_resource.id,
subset.base_font,
font_subset->num_glyphs - 1,
- descriptor.id);
+ descriptor.id,
+ encoding.id);
for (i = 0; i < font_subset->num_glyphs; i++)
_cairo_output_stream_printf (surface->output,
@@ -2819,14 +2836,14 @@ _cairo_pdf_surface_show_glyphs (void *
-scaled_font->scale.yy,
glyphs[i].x,
glyphs[i].y,
- subset_glyph_index);
+ subset_glyph_index + 1);
current_subset_id = subset_id;
} else {
_cairo_output_stream_printf (surface->output,
"%f %f Td <%02x> Tj\r\n",
(glyphs[i].x - glyphs[i-1].x)/scaled_font->scale.xx,
(glyphs[i].y - glyphs[i-1].y)/scaled_font->scale.yy,
- subset_glyph_index);
+ subset_glyph_index + 1);
}
}
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 45d9fe7..238e2a5 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -84,7 +84,7 @@ typedef struct cairo_ps_surface {
} cairo_ps_surface_t;
-#define PS_SURFACE_MAX_GLYPHS_PER_FONT 256
+#define PS_SURFACE_MAX_GLYPHS_PER_FONT 255
/* A word wrap stream can be used as a filter to do word wrapping on
* top of an existing output stream. The word wrapping is quite
@@ -484,7 +484,7 @@ _cairo_ps_surface_emit_truetype_font_sub
/* FIXME: Figure out how subset->x_max etc maps to the /FontBBox */
- for (i = 1; i < font_subset->num_glyphs; i++)
+ for (i = 1; i <= font_subset->num_glyphs; i++)
_cairo_output_stream_printf (surface->final_stream,
"Encoding %d /g%d put\n", i, i);
@@ -493,7 +493,7 @@ _cairo_ps_surface_emit_truetype_font_sub
"/.notdef 0 def\n",
font_subset->num_glyphs);
- for (i = 1; i < font_subset->num_glyphs; i++)
+ for (i = 1; i <= font_subset->num_glyphs; i++)
_cairo_output_stream_printf (surface->final_stream,
"/g%d %d def\n", i, i);
@@ -2217,12 +2217,12 @@ _cairo_ps_surface_show_glyphs (void
}
if (i == last) {
- _cairo_output_stream_printf (surface->stream, "<%02x> S\n", glyph_ids[i].glyph_id);
+ _cairo_output_stream_printf (surface->stream, "<%02x> S\n", glyph_ids[i].glyph_id + 1);
} else {
word_wrap = _word_wrap_stream_create (surface->stream, 79);
_cairo_output_stream_printf (word_wrap, "<");
for (j = i; j < last+1; j++)
- _cairo_output_stream_printf (word_wrap, "%02x", glyph_ids[j].glyph_id);
+ _cairo_output_stream_printf (word_wrap, "%02x", glyph_ids[j].glyph_id + 1);
_cairo_output_stream_printf (word_wrap, ">\n[");
if (horizontal) {
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 86509df..0c48168 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -243,7 +243,7 @@ _cairo_truetype_font_create (cairo_scale
}
font->base.base_font[i] = '\0';
- font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
+ font->base.widths = calloc (font->num_glyphs_in_face + 1, sizeof (int));
if (font->base.widths == NULL)
goto fail5;
@@ -813,6 +813,7 @@ _cairo_truetype_subset_init (cairo_truet
if (status)
return status;
+ cairo_truetype_font_use_glyph (font, 0);
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
parent_glyph = font->scaled_font_subset->glyphs[i];
cairo_truetype_font_use_glyph (font, parent_glyph);
--
1.4.3.4
More information about the cairo
mailing list