[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