[cairo-commit] 2 commits - src/cairo-pdf-operators.c src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-scaled-font-subsets-private.h src/cairo-truetype-subset.c

Adrian Johnson ajohnson at kemper.freedesktop.org
Sat Oct 2 03:39:15 PDT 2010


 src/cairo-pdf-operators.c               |   73 ++++++++++++++++++++++++++++----
 src/cairo-pdf-surface.c                 |    2 
 src/cairo-ps-surface.c                  |    2 
 src/cairo-scaled-font-subsets-private.h |   28 ++++++++++--
 src/cairo-truetype-subset.c             |   31 ++++++++++---
 5 files changed, 116 insertions(+), 20 deletions(-)

New commits:
commit 7d2979e446e2e10b6c5ace711549d25690b477ed
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Oct 2 16:58:06 2010 +0930

    Don't embed cmap in TrueType fonts embedded in PostScript
    
    it doesn't print on a LaserJet 4050

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 3265312..7efae8b 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -4261,7 +4261,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t		*surface,
     if (subset_resource.id == 0)
 	return CAIRO_STATUS_SUCCESS;
 
-    status = _cairo_truetype_subset_init (&subset, font_subset);
+    status = _cairo_truetype_subset_init_pdf (&subset, font_subset);
     if (unlikely (status))
 	return status;
 
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 1c5d7a9..b8f1a53 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -402,7 +402,7 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t		*surface,
     cairo_status_t status;
     unsigned int i, begin, end;
 
-    status = _cairo_truetype_subset_init (&subset, font_subset);
+    status = _cairo_truetype_subset_init_ps (&subset, font_subset);
     if (unlikely (status))
 	return status;
 
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index 44b037a..8de49fa 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -447,7 +447,29 @@ typedef struct _cairo_truetype_subset {
  * #cairo_scaled_font_t and the font backend in use) generate a
  * truetype file corresponding to @font_subset and initialize
  * @truetype_subset with information about the subset and the truetype
- * data.
+ * data. The generated font will be suitable for embedding in
+ * PostScript.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS if successful,
+ * %CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a
+ * truetype file, or an non-zero value indicating an error.  Possible
+ * errors include %CAIRO_STATUS_NO_MEMORY.
+ **/
+cairo_private cairo_status_t
+_cairo_truetype_subset_init_ps (cairo_truetype_subset_t    *truetype_subset,
+				cairo_scaled_font_subset_t *font_subset);
+
+/**
+ * _cairo_truetype_subset_init:
+ * @truetype_subset: a #cairo_truetype_subset_t to initialize
+ * @font_subset: the #cairo_scaled_font_subset_t to initialize from
+ *
+ * If possible (depending on the format of the underlying
+ * #cairo_scaled_font_t and the font backend in use) generate a
+ * truetype file corresponding to @font_subset and initialize
+ * @truetype_subset with information about the subset and the truetype
+ * data. The generated font will be suitable for embedding in
+ * PDF.
  *
  * Return value: %CAIRO_STATUS_SUCCESS if successful,
  * %CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a
@@ -455,8 +477,8 @@ typedef struct _cairo_truetype_subset {
  * errors include %CAIRO_STATUS_NO_MEMORY.
  **/
 cairo_private cairo_status_t
-_cairo_truetype_subset_init (cairo_truetype_subset_t    *truetype_subset,
-			     cairo_scaled_font_subset_t	*font_subset);
+_cairo_truetype_subset_init_pdf (cairo_truetype_subset_t    *truetype_subset,
+				 cairo_scaled_font_subset_t *font_subset);
 
 /**
  * _cairo_truetype_subset_fini:
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index b774bd2..55f97b0 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -92,7 +92,7 @@ struct _cairo_truetype_font {
     unsigned long last_boundary;
     int *parent_to_subset;
     cairo_status_t status;
-
+    cairo_bool_t is_pdf;
 };
 
 /*
@@ -132,6 +132,7 @@ _cairo_truetype_font_set_error (cairo_truetype_font_t *font,
 
 static cairo_status_t
 _cairo_truetype_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
+			     cairo_bool_t is_pdf,
 			     cairo_truetype_font_t      **font_return)
 {
     cairo_status_t status;
@@ -206,6 +207,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
 	goto fail2;
     }
 
+    font->is_pdf = is_pdf;
     font->base.num_glyphs = 0;
     font->base.x_min = (int16_t) be16_to_cpu (head.x_min);
     font->base.y_min = (int16_t) be16_to_cpu (head.y_min);
@@ -1065,7 +1067,7 @@ cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
 
     font->num_tables = 0;
     pos = 0;
-    if (font->scaled_font_subset->is_latin)
+    if (font->is_pdf && font->scaled_font_subset->is_latin)
 	pos++;
     if (has_cvt)
         pos++;
@@ -1074,7 +1076,7 @@ cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
     cairo_truetype_font_add_truetype_table (font, TT_TAG_glyf, cairo_truetype_font_write_glyf_table, pos);
 
     pos = 0;
-    if (font->scaled_font_subset->is_latin)
+    if (font->is_pdf && font->scaled_font_subset->is_latin)
 	cairo_truetype_font_add_truetype_table (font, TT_TAG_cmap, cairo_truetype_font_write_cmap_table, pos++);
     if (has_cvt)
         cairo_truetype_font_add_truetype_table (font, TT_TAG_cvt, cairo_truetype_font_write_generic_table, pos++);
@@ -1090,9 +1092,10 @@ cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
         cairo_truetype_font_add_truetype_table (font, TT_TAG_prep, cairo_truetype_font_write_generic_table, pos);
 }
 
-cairo_status_t
-_cairo_truetype_subset_init (cairo_truetype_subset_t    *truetype_subset,
-			     cairo_scaled_font_subset_t	*font_subset)
+static cairo_status_t
+cairo_truetype_subset_init_internal (cairo_truetype_subset_t     *truetype_subset,
+				      cairo_scaled_font_subset_t *font_subset,
+				      cairo_bool_t                is_pdf)
 {
     cairo_truetype_font_t *font = NULL;
     cairo_status_t status;
@@ -1103,7 +1106,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t    *truetype_subset,
     const unsigned long *string_offsets = NULL;
     unsigned long num_strings = 0;
 
-    status = _cairo_truetype_font_create (font_subset, &font);
+    status = _cairo_truetype_font_create (font_subset, is_pdf, &font);
     if (unlikely (status))
 	return status;
 
@@ -1201,6 +1204,20 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t    *truetype_subset,
     return status;
 }
 
+cairo_status_t
+_cairo_truetype_subset_init_ps (cairo_truetype_subset_t    *truetype_subset,
+				cairo_scaled_font_subset_t	*font_subset)
+{
+    return cairo_truetype_subset_init_internal (truetype_subset, font_subset, FALSE);
+}
+
+cairo_status_t
+_cairo_truetype_subset_init_pdf (cairo_truetype_subset_t    *truetype_subset,
+				cairo_scaled_font_subset_t	*font_subset)
+{
+    return cairo_truetype_subset_init_internal (truetype_subset, font_subset, TRUE);
+}
+
 void
 _cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
 {
commit cd74f5edabf653d1c1c6daacea3626ba2548d5e0
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Oct 2 12:34:42 2010 +0930

    pdf-operators: word wrap latin text strings

diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index 21592b5..7613b41 100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -169,8 +169,10 @@ typedef struct _word_wrap_stream {
     int max_column;
     int column;
     cairo_bool_t last_write_was_space;
+    cairo_bool_t in_string;
     cairo_bool_t in_hexstring;
-    cairo_bool_t empty_hexstring;
+    cairo_bool_t empty_string;
+    cairo_bool_t in_escape;
 } word_wrap_stream_t;
 
 static int
@@ -179,7 +181,7 @@ _count_word_up_to (const unsigned char *s, int length)
     int word = 0;
 
     while (length--) {
-	if (! (_cairo_isspace (*s) || *s == '<')) {
+	if (! (_cairo_isspace (*s) || *s == '<' || *s == '(')) {
 	    s++;
 	    word++;
 	} else {
@@ -213,6 +215,33 @@ _count_hexstring_up_to (const unsigned char *s, int length, int columns)
     return word;
 }
 
+/* Count up to either the end of the string or the number of columns
+ * remaining.
+ */
+static int
+_count_string_up_to (const unsigned char *s, int length, int columns, cairo_bool_t *in_escape)
+{
+    int word = 0;
+
+    while (length--) {
+	if (*in_escape || *s != ')') {
+	    word++;
+	    if (!*in_escape && *s++ == '\\')
+		*in_escape = TRUE;
+	    else
+		*in_escape = FALSE;
+	} else {
+	    return word;
+	}
+
+	columns--;
+	if (columns < 0 && word > 0)
+	    return word;
+    }
+
+    return word;
+}
+
 static cairo_status_t
 _word_wrap_stream_write (cairo_output_stream_t  *base,
 			 const unsigned char	*data,
@@ -225,7 +254,7 @@ _word_wrap_stream_write (cairo_output_stream_t  *base,
     while (length) {
 	if (*data == '<') {
 	    stream->in_hexstring = TRUE;
-	    stream->empty_hexstring = TRUE;
+	    stream->empty_string = TRUE;
 	    stream->last_write_was_space = FALSE;
 	    data++;
 	    length--;
@@ -238,7 +267,27 @@ _word_wrap_stream_write (cairo_output_stream_t  *base,
 	    length--;
 	    _cairo_output_stream_printf (stream->output, ">");
 	    stream->column++;
-	} else if (_cairo_isspace (*data)) {
+	} else if (*data == '(') {
+	    stream->in_string = TRUE;
+	    stream->in_escape = FALSE;
+	    stream->empty_string = TRUE;
+	    stream->last_write_was_space = FALSE;
+	    data++;
+	    length--;
+	    _cairo_output_stream_printf (stream->output, "(");
+	    stream->column++;
+	} else if (*data == ')') {
+	    stream->in_string = FALSE;
+	    stream->last_write_was_space = FALSE;
+	    data++;
+	    length--;
+	    _cairo_output_stream_printf (stream->output, ")");
+	    stream->column++;
+	    if (stream->column > stream->max_column) {
+		_cairo_output_stream_printf (stream->output, "\n");
+		stream->column = 0;
+	    }
+	} else if (_cairo_isspace (*data) && !stream->in_string) {
 	    newline =  (*data == '\n' || *data == '\r');
 	    if (! newline && stream->column >= stream->max_column) {
 		_cairo_output_stream_printf (stream->output, "\n");
@@ -257,6 +306,9 @@ _word_wrap_stream_write (cairo_output_stream_t  *base,
 	    if (stream->in_hexstring) {
 		word = _count_hexstring_up_to (data, length,
 					       MAX (stream->max_column - stream->column, 0));
+	    } else if (stream->in_string) {
+		word = _count_string_up_to (data, length,
+					    MAX (stream->max_column - stream->column, 0), &stream->in_escape);
 	    } else {
 		word = _count_word_up_to (data, length);
 	    }
@@ -264,8 +316,11 @@ _word_wrap_stream_write (cairo_output_stream_t  *base,
 	     * string word from a previous call to write. */
 	    if (stream->column + word >= stream->max_column) {
 		if (stream->last_write_was_space ||
-		    (stream->in_hexstring && !stream->empty_hexstring))
+		    (stream->in_hexstring && !stream->empty_string) ||
+		    (stream->in_string && !stream->empty_string && !stream->in_escape))
 		{
+		    if (stream->in_string)
+			_cairo_output_stream_printf (stream->output, "\\");
 		    _cairo_output_stream_printf (stream->output, "\n");
 		    stream->column = 0;
 		}
@@ -275,8 +330,8 @@ _word_wrap_stream_write (cairo_output_stream_t  *base,
 	    length -= word;
 	    stream->column += word;
 	    stream->last_write_was_space = FALSE;
-	    if (stream->in_hexstring)
-		stream->empty_hexstring = FALSE;
+	    if (stream->in_hexstring || stream->in_string)
+		stream->empty_string = FALSE;
 	}
     }
 
@@ -314,7 +369,9 @@ _word_wrap_stream_create (cairo_output_stream_t *output, int max_column)
     stream->column = 0;
     stream->last_write_was_space = FALSE;
     stream->in_hexstring = FALSE;
-    stream->empty_hexstring = TRUE;
+    stream->in_string = FALSE;
+    stream->in_escape = FALSE;
+    stream->empty_string = TRUE;
 
     return &stream->base;
 }


More information about the cairo-commit mailing list