[cairo-commit] 3 commits - src/cairo-scaled-font-subsets.c src/cairo-type1-fallback.c
Adrian Johnson
ajohnson at kemper.freedesktop.org
Sat Apr 5 07:06:16 PDT 2008
src/cairo-scaled-font-subsets.c | 1
src/cairo-type1-fallback.c | 94 ++++++++++++----------------------------
2 files changed, 31 insertions(+), 64 deletions(-)
New commits:
commit 0d5902b7167f8cb4bfc96fd813003cd220441151
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sat Apr 5 23:33:29 2008 +1030
Type1-fallback: Use correct glyph metrics for .notdef glyph
Bug 15348 references the following PDF that was printing incorrectly
when running through poppler and cairo to generate PostScript.
http://launchpadlibrarian.net/12921700/UbuntuDesktop.pdf
The PostScript output had too much space between each word causing
strings of glyphs printed with the TJ operator to overlap.
The original PDF file contains an CFF font with CID Identity-H
encoding. The PDF file is using character code 0 (glyph 0 due to
Identity-H encoding) as a space character. The CFF specification
defines glyph 0 to be the .notdef glyph.
The PS backend subsets CFF fonts as a Type1-fallback
font. Type1-fallback creates it's own empty .notdef glyph with an
arbitrary glyph advance of 500. The problem here is the TJ operator
used to output the glyphs depends on the glyph advance being
correct. pdf-operators.c uses the glyph advance returned by
_scaled_glyph_init(). However the PostScript interpreter sees the
glyph advance of 500 for .notdef. This problem does not occur when
generating PDF as the PDF font dictionary contains an list of glyph
advances that override the font metrics.
Fix this by making Type1-fallback not treat .notdef as special and to
create it the path and metrics obtained from _scaled_glyph_init(). As
a special case, make it not fail if _scaled_glyph_init() is unable to
return a path for .notdef. This was probably the reason Type1-fallback
previously created it's own .notdef glyph as calling
_scaled_glyph_init(_GLYPH_INFO_PATH) for glyph 0 returns
CAIRO_INT_STATUS_UNSUPPORTED for some fonts.
This ensures the Type1-fallback font metrics match the metrics used
by pdf-operators.c to position the glyphs. This also results in the
removal of some duplicated code.
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index 0d81ccb..539ddf2 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -332,33 +332,6 @@ charstring_encrypt (cairo_array_t *data)
}
static cairo_int_status_t
-create_notdef_charstring (cairo_array_t *data, cairo_charstring_type_t type)
-{
- cairo_status_t status;
-
- /* We're passing constants below, so we know the 0 values will
- * only use 1 byte each, and the 500 values will use 2 bytes
- * each. Then 2 more for each of the commands is 10 total. */
- status = _cairo_array_grow_by (data, 10);
- if (status)
- return status;
-
- if (type == CAIRO_CHARSTRING_TYPE1) {
- charstring_encode_integer (data, 0, type);
- charstring_encode_integer (data, 0, type);
-
- /* The width is arbitrary. */
- charstring_encode_integer (data, 500, type);
- charstring_encode_integer (data, 0, type);
- charstring_encode_command (data, CHARSTRING_sbw);
- }
-
- charstring_encode_command (data, CHARSTRING_endchar);
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
cairo_type1_font_create_charstring (cairo_type1_font_t *font,
int subset_index,
int glyph_index,
@@ -369,6 +342,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
cairo_scaled_glyph_t *scaled_glyph;
t1_path_info_t path_info;
cairo_text_extents_t *metrics;
+ cairo_bool_t emit_path = TRUE;
/* This call may return CAIRO_INT_STATUS_UNSUPPORTED for bitmap fonts. */
status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
@@ -376,6 +350,16 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
CAIRO_SCALED_GLYPH_INFO_METRICS|
CAIRO_SCALED_GLYPH_INFO_PATH,
&scaled_glyph);
+
+ /* It is ok for the .notdef glyph to not have a path available. We
+ * just need the metrics to emit an empty glyph. */
+ if (glyph_index == 0 && status == CAIRO_INT_STATUS_UNSUPPORTED) {
+ emit_path = FALSE;
+ status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
+ glyph_index,
+ CAIRO_SCALED_GLYPH_INFO_METRICS,
+ &scaled_glyph);
+ }
if (status)
return status;
@@ -418,15 +402,17 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
}
path_info.data = data;
path_info.type = type;
- status = _cairo_path_fixed_interpret (scaled_glyph->path,
- CAIRO_DIRECTION_FORWARD,
- _charstring_move_to,
- _charstring_line_to,
- _charstring_curve_to,
- _charstring_close_path,
- &path_info);
- if (status)
- return status;
+ if (emit_path) {
+ status = _cairo_path_fixed_interpret (scaled_glyph->path,
+ CAIRO_DIRECTION_FORWARD,
+ _charstring_move_to,
+ _charstring_line_to,
+ _charstring_curve_to,
+ _charstring_close_path,
+ &path_info);
+ if (status)
+ return status;
+ }
status = _cairo_array_grow_by (data, 1);
if (status)
@@ -455,7 +441,7 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
"2 index /CharStrings %d dict dup begin\n",
font->scaled_font_subset->num_glyphs + 1);
- for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
+ for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
_cairo_array_truncate (&data, 0);
/* four "random" bytes required by encryption algorithm */
status = _cairo_array_append_multiple (&data, zeros, 4);
@@ -473,6 +459,8 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
_cairo_output_stream_printf (encrypted_output, "/%s %d RD ",
font->scaled_font_subset->glyph_names[i],
length);
+ } else if (i == 0) {
+ _cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length);
} else {
_cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length);
}
@@ -482,24 +470,6 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
_cairo_output_stream_printf (encrypted_output, " ND\n");
}
- /* All type 1 fonts must have a /.notdef charstring */
-
- _cairo_array_truncate (&data, 0);
- /* four "random" bytes required by encryption algorithm */
- status = _cairo_array_append_multiple (&data, zeros, 4);
- if (status)
- goto fail;
- status = create_notdef_charstring (&data, CAIRO_CHARSTRING_TYPE1);
- if (status)
- goto fail;
- charstring_encrypt (&data);
- length = _cairo_array_num_elements (&data);
- _cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length);
- _cairo_output_stream_write (encrypted_output,
- _cairo_array_index (&data, 0),
- length);
- _cairo_output_stream_printf (encrypted_output, " ND\n");
-
fail:
_cairo_array_fini (&data);
return status;
@@ -856,14 +826,10 @@ _cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
if (status)
goto fail2;
- if (i == 0) {
- status = create_notdef_charstring (&charstring, CAIRO_CHARSTRING_TYPE2);
- } else {
- status = cairo_type1_font_create_charstring (font, i,
- font->scaled_font_subset->glyphs[i],
- CAIRO_CHARSTRING_TYPE2,
- &charstring);
- }
+ status = cairo_type1_font_create_charstring (font, i,
+ font->scaled_font_subset->glyphs[i],
+ CAIRO_CHARSTRING_TYPE2,
+ &charstring);
if (status)
goto fail2;
commit 03d2b098ff245ff6724b1d83a121f5ce9dcd0b51
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sat Apr 5 21:15:15 2008 +1030
Type1-fallback: Use correct glyph advance in Type 1 charstrings
5050c55f93af fixed type1-fallback to use the glyph advance instead of
glyph width in the stored glyph metrics in the font. However it did
not fix the same bug in Type 2 charstrings (used by CFF fallback in
PDF). This problem was not noticed since the glyph widths in the PDF
font dictionary overrides these values.
Fix this in case any software reading cairo PDFs uses these values.
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index a0fe5da..0d81ccb 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -411,7 +411,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
} else {
- charstring_encode_integer (data, (int) scaled_glyph->metrics.width, type);
+ charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
path_info.current_x = 0;
path_info.current_y = 0;
commit 40cee8c57879d37d77c5a93de8f7bdef28851923
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sat Apr 5 20:53:39 2008 +1030
Add assert to scaled_glyph_lookup in scaled-font-subsets
If _cairo_scaled_glyph_lookup() returns CAIRO_INT_STATUS_UNSUPPORTED
it will be caught by the ASSERT_NOT_REACHED in
_emit_unscaled_font_subset in PS/PDF. It is more useful to catch this
closer to the source.
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index f74c89b..7d89abc 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -339,6 +339,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
scaled_font_glyph_index,
CAIRO_SCALED_GLYPH_INFO_METRICS,
&scaled_glyph);
+ assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
if (status)
return status;
More information about the cairo-commit
mailing list