[cairo-commit] 2 commits - src/cairo-cff-subset.c

Adrian Johnson ajohnson at kemper.freedesktop.org
Sun Aug 21 03:48:54 PDT 2011


 src/cairo-cff-subset.c |   37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)

New commits:
commit cdb00dec4231d2dd3c2f9c98c3533a716d71cf8c
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Aug 21 20:12:42 2011 +0930

    cff-subset: don't easily give up parsing a charstring if we already have the width
    
    The 2 byte operators can be ignored of we don't need or have already found
    the width.

diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index 6ded77a..71465bb 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -1436,9 +1436,13 @@ type2_decode_integer (unsigned char *p, int *integer)
  * used.
  *
  * The width, if present, is the first integer in the charstring. The
- * only way to confirm if an integer at the start of the charstring is
+ * only way to confirm if the integer at the start of the charstring is
  * the width is when the first stack clearing operator is parsed,
  * check if there is an extra integer left over on the stack.
+ *
+ * When the first stack clearing operator is encountered
+ * type2_find_width is set to FALSE and type2_found_width is set to
+ * TRUE if an extra argument is found, otherwise FALSE.
  */
 static cairo_status_t
 cairo_cff_parse_charstring (cairo_cff_font_t *font,
@@ -1575,13 +1579,15 @@ cairo_cff_parse_charstring (cairo_cff_font_t *font,
         } else if (*p == 12) {
             /* 2 byte instruction */
 
-	    /* Most of the 2 byte operators */
-	    if (need_width && (p[1] < 0x22 || p[1] > 0x25))
+	    /* All the 2 byte operators are either not valid before a
+	     * stack clearing operator or they are one of the
+	     * arithmetic, storage, or conditional operators. */
+	    if (need_width && font->type2_find_width)
 		return CAIRO_INT_STATUS_UNSUPPORTED;
 
             p += 2;
 	    font->type2_stack_top_is_int = FALSE;
-        } else {
+	} else {
             /* 1 byte instruction */
             p++;
 	    font->type2_stack_top_is_int = FALSE;
commit 23dfd92b29508623fce8570fc625a79df12bd883
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Aug 21 18:27:07 2011 +0930

    cff-subset: fallback when parsing the charstrings in bare cff fonts fails
    
    We need to parse all used charstrings in bare CFF fonts to extract the widths.

diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index d311514..6ded77a 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -1592,9 +1592,9 @@ cairo_cff_parse_charstring (cairo_cff_font_t *font,
 }
 
 static cairo_status_t
-cairo_cff_find_subroutines_used (cairo_cff_font_t  *font,
-                                 unsigned char *charstring, int length,
-                                 int glyph_id, int subset_id)
+cairo_cff_find_width_and_subroutines_used (cairo_cff_font_t  *font,
+					   unsigned char *charstring, int length,
+					   int glyph_id, int subset_id)
 {
     cairo_status_t status;
     int width;
@@ -1612,6 +1612,8 @@ cairo_cff_find_subroutines_used (cairo_cff_font_t  *font,
     font->type2_width = 0;
 
     status = cairo_cff_parse_charstring (font, charstring, length, glyph_id, TRUE);
+    if (status)
+	return status;
 
     if (!font->is_opentype) {
         if (font->is_cid) {
@@ -1629,7 +1631,7 @@ cairo_cff_find_subroutines_used (cairo_cff_font_t  *font,
         font->widths[subset_id] = width;
     }
 
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
@@ -1651,11 +1653,20 @@ cairo_cff_font_subset_charstrings_and_subroutines (cairo_cff_font_t  *font)
             return status;
 
 	if (font->subset_subroutines) {
-	    status = cairo_cff_find_subroutines_used (font, element->data, element->length, glyph, i);
+	    status = cairo_cff_find_width_and_subroutines_used (font,
+								element->data, element->length,
+								glyph, i);
 	    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+		/* If parsing the charstrings fails we embed all the
+		 * subroutines. But if the font is not opentype we
+		 * need to successfully parse all charstrings to get
+		 * the widths. */
 		font->subset_subroutines = FALSE;
-	    } else if (unlikely (status))
+		if (!font->is_opentype)
+		    return status;
+	    } else if (unlikely (status)) {
                 return status;
+	    }
         }
     }
 


More information about the cairo-commit mailing list