[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