Blame SOURCES/0004-font-Generate-PDFs-with-correct-font-names.patch

ac1da3
From 97f6e2005d9cbc9c9dd7cc21445df7c08e084c83 Mon Sep 17 00:00:00 2001
ac1da3
From: Marek Kasik <mkasik@redhat.com>
ac1da3
Date: Thu, 9 Jan 2014 17:28:32 +0100
ac1da3
Subject: [PATCH] font: Generate PDFs with correct font names
ac1da3
ac1da3
Escape PostScript names of loaded fonts. These can not
ac1da3
contain white spaces and delimiter characters when saving
ac1da3
them to a PostScript file or a PDF file.
ac1da3
---
ac1da3
 src/cairo-cff-subset.c                  |  2 ++
ac1da3
 src/cairo-scaled-font-subsets-private.h | 15 +++++++++++++
ac1da3
 src/cairo-scaled-font-subsets.c         | 40 +++++++++++++++++++++++++++++++++
ac1da3
 src/cairo-truetype-subset.c             | 35 +++--------------------------
ac1da3
 src/cairo-type1-subset.c                |  9 +++-----
ac1da3
 5 files changed, 63 insertions(+), 38 deletions(-)
ac1da3
ac1da3
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
ac1da3
index c420bd4..1ae032c 100644
ac1da3
--- a/src/cairo-cff-subset.c
ac1da3
+++ b/src/cairo-cff-subset.c
ac1da3
@@ -899,6 +899,8 @@ cairo_cff_font_read_name (cairo_cff_font_t *font)
ac1da3
 
ac1da3
         memcpy (font->ps_name, p, len);
ac1da3
         font->ps_name[len] = 0;
ac1da3
+
ac1da3
+        status = _cairo_escape_ps_name (&font->ps_name);
ac1da3
     }
ac1da3
     cff_index_fini (&index);
ac1da3
 
ac1da3
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
ac1da3
index dd19962..866e63d 100644
ac1da3
--- a/src/cairo-scaled-font-subsets-private.h
ac1da3
+++ b/src/cairo-scaled-font-subsets-private.h
ac1da3
@@ -715,6 +715,21 @@ _cairo_truetype_get_style (cairo_scaled_font_t  	 *scaled_font,
ac1da3
 			   cairo_bool_t			 *bold,
ac1da3
 			   cairo_bool_t			 *italic);
ac1da3
 
ac1da3
+/**
ac1da3
+ * _cairo_escape_ps_name:
ac1da3
+ * @ps_name: returns the PostScript name with all invalid characters escaped
ac1da3
+ *
ac1da3
+ * Ensure that PostSript name is a valid PDF/PostSript name object.
ac1da3
+ * In PDF names are treated as UTF8 and non ASCII bytes, ' ',
ac1da3
+ * and '#' are encoded as '#' followed by 2 hex digits that
ac1da3
+ * encode the byte.
ac1da3
+ *
ac1da3
+ * Return value: %CAIRO_STATUS_SUCCESS if successful. Possible errors include
ac1da3
+ * %CAIRO_STATUS_NO_MEMORY.
ac1da3
+ **/
ac1da3
+cairo_private cairo_int_status_t
ac1da3
+_cairo_escape_ps_name (char **ps_name);
ac1da3
+
ac1da3
 #endif /* CAIRO_HAS_FONT_SUBSET */
ac1da3
 
ac1da3
 #endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */
ac1da3
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
ac1da3
index e78e0c2..2121761 100644
ac1da3
--- a/src/cairo-scaled-font-subsets.c
ac1da3
+++ b/src/cairo-scaled-font-subsets.c
ac1da3
@@ -1256,4 +1256,44 @@ CLEANUP_HASH:
ac1da3
     return status;
ac1da3
 }
ac1da3
 
ac1da3
+cairo_int_status_t
ac1da3
+_cairo_escape_ps_name (char **ps_name)
ac1da3
+{
ac1da3
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
ac1da3
+
ac1da3
+    /* Ensure PS name is a valid PDF/PS name object. In PDF names are
ac1da3
+     * treated as UTF8 and non ASCII bytes, ' ', and '#' are encoded
ac1da3
+     * as '#' followed by 2 hex digits that encode the byte. By also
ac1da3
+     * encoding the characters in the reserved string we ensure the
ac1da3
+     * name is also PS compatible. */
ac1da3
+    if (*ps_name) {
ac1da3
+	static const char *reserved = "()<>[]{}/%#\\";
ac1da3
+	char buf[128]; /* max name length is 127 bytes */
ac1da3
+	char *src = *ps_name;
ac1da3
+	char *dst = buf;
ac1da3
+
ac1da3
+	while (*src && dst < buf + 127) {
ac1da3
+	    unsigned char c = *src;
ac1da3
+	    if (c < 0x21 || c > 0x7e || strchr (reserved, c)) {
ac1da3
+		if (dst + 4 > buf + 127)
ac1da3
+		    break;
ac1da3
+
ac1da3
+		snprintf (dst, 4, "#%02X", c);
ac1da3
+		src++;
ac1da3
+		dst += 3;
ac1da3
+	    } else {
ac1da3
+		*dst++ = *src++;
ac1da3
+	    }
ac1da3
+	}
ac1da3
+	*dst = 0;
ac1da3
+	free (*ps_name);
ac1da3
+	*ps_name = strdup (buf);
ac1da3
+	if (*ps_name == NULL) {
ac1da3
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
ac1da3
+	}
ac1da3
+    }
ac1da3
+
ac1da3
+    return status;
ac1da3
+}
ac1da3
+
ac1da3
 #endif /* CAIRO_HAS_FONT_SUBSET */
ac1da3
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
ac1da3
index 18ee685..3d55fef 100644
ac1da3
--- a/src/cairo-truetype-subset.c
ac1da3
+++ b/src/cairo-truetype-subset.c
ac1da3
@@ -1566,38 +1566,9 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t  	 *scaled_font,
ac1da3
 
ac1da3
     free (name);
ac1da3
 
ac1da3
-    /* Ensure PS name is a valid PDF/PS name object. In PDF names are
ac1da3
-     * treated as UTF8 and non ASCII bytes, ' ', and '#' are encoded
ac1da3
-     * as '#' followed by 2 hex digits that encode the byte. By also
ac1da3
-     * encoding the characters in the reserved string we ensure the
ac1da3
-     * name is also PS compatible. */
ac1da3
-    if (ps_name) {
ac1da3
-	static const char *reserved = "()<>[]{}/%#\\";
ac1da3
-	char buf[128]; /* max name length is 127 bytes */
ac1da3
-	char *src = ps_name;
ac1da3
-	char *dst = buf;
ac1da3
-
ac1da3
-	while (*src && dst < buf + 127) {
ac1da3
-	    unsigned char c = *src;
ac1da3
-	    if (c < 0x21 || c > 0x7e || strchr (reserved, c)) {
ac1da3
-		if (dst + 4 > buf + 127)
ac1da3
-		    break;
ac1da3
-
ac1da3
-		snprintf (dst, 4, "#%02X", c);
ac1da3
-		src++;
ac1da3
-		dst += 3;
ac1da3
-	    } else {
ac1da3
-		*dst++ = *src++;
ac1da3
-	    }
ac1da3
-	}
ac1da3
-	*dst = 0;
ac1da3
-	free (ps_name);
ac1da3
-	ps_name = strdup (buf);
ac1da3
-	if (ps_name == NULL) {
ac1da3
-	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
ac1da3
-	    goto fail;
ac1da3
-	}
ac1da3
-    }
ac1da3
+    status = _cairo_escape_ps_name (&ps_name);
ac1da3
+    if (unlikely(status))
ac1da3
+	goto fail;
ac1da3
 
ac1da3
     *ps_name_out = ps_name;
ac1da3
     *font_name_out = family_name;
ac1da3
diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
ac1da3
index 99830b4..3b2cc0a 100644
ac1da3
--- a/src/cairo-type1-subset.c
ac1da3
+++ b/src/cairo-type1-subset.c
ac1da3
@@ -407,6 +407,7 @@ cairo_type1_font_subset_get_fontname (cairo_type1_font_subset_t *font)
ac1da3
     const char *start, *end, *segment_end;
ac1da3
     char *s;
ac1da3
     int i;
ac1da3
+    cairo_status_t status;
ac1da3
 
ac1da3
     segment_end = font->header_segment + font->header_segment_size;
ac1da3
     start = find_token (font->header_segment, segment_end, "/FontName");
ac1da3
@@ -447,13 +448,9 @@ cairo_type1_font_subset_get_fontname (cairo_type1_font_subset_t *font)
ac1da3
     if (unlikely (font->base.base_font == NULL))
ac1da3
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
ac1da3
 
ac1da3
-    s = font->base.base_font;
ac1da3
-    while (*s && !is_ps_delimiter(*s))
ac1da3
-	s++;
ac1da3
-
ac1da3
-    *s = 0;
ac1da3
+    status = _cairo_escape_ps_name (&font->base.base_font);
ac1da3
 
ac1da3
-    return CAIRO_STATUS_SUCCESS;
ac1da3
+    return status;
ac1da3
 }
ac1da3
 
ac1da3
 static cairo_status_t
ac1da3
-- 
ac1da3
1.8.4.2
ac1da3