[cairo-commit] 11 commits - src/cairo-cff-subset.c src/cairoint.h src/cairo-pdf-operators.c src/cairo-pdf-operators-private.h src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-scaled-font-subsets.c src/cairo-scaled-font-subsets-private.h src/cairo-truetype-subset.c src/cairo-type1-fallback.c src/cairo-type1-subset.c
Adrian Johnson
ajohnson at kemper.freedesktop.org
Fri Oct 1 04:22:40 PDT 2010
src/cairo-cff-subset.c | 20 +
src/cairo-pdf-operators-private.h | 2
src/cairo-pdf-operators.c | 64 ++++--
src/cairo-pdf-surface.c | 191 ++++++++++++-----
src/cairo-ps-surface.c | 32 ++-
src/cairo-scaled-font-subsets-private.h | 26 ++
src/cairo-scaled-font-subsets.c | 341 +++++++++++++++++++++++---------
src/cairo-truetype-subset.c | 123 ++++++++---
src/cairo-type1-fallback.c | 27 +-
src/cairo-type1-subset.c | 136 +++++++++++-
src/cairoint.h | 2
11 files changed, 733 insertions(+), 231 deletions(-)
New commits:
commit 165a14b5646d582781d119874f549ec9a02d7f53
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 1 19:18:28 2010 +0930
pdf-operators: fix bug that was causing unnecessary repositioning of text
This optimizes the output to increase the maximum amount of text that
is emitted with a single Tj operator.
diff --git a/src/cairo-pdf-operators-private.h b/src/cairo-pdf-operators-private.h
index 1f5ee17..14d60b6 100644
--- a/src/cairo-pdf-operators-private.h
+++ b/src/cairo-pdf-operators-private.h
@@ -83,6 +83,7 @@ typedef struct _cairo_pdf_operators {
int hex_width;
cairo_bool_t is_latin;
int num_glyphs;
+ double glyph_buf_x_pos;
cairo_pdf_glyph_t glyphs[PDF_GLYPH_BUFFER_SIZE];
/* PDF line style */
diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index 2d718ed..21592b5 100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -1016,6 +1016,7 @@ _cairo_pdf_operators_flush_glyphs (cairo_pdf_operators_t *pdf_operators)
}
pdf_operators->num_glyphs = 0;
+ pdf_operators->glyph_buf_x_pos = pdf_operators->cur_x;
status2 = _cairo_output_stream_destroy (word_wrap_stream);
if (status == CAIRO_STATUS_SUCCESS)
status = status2;
@@ -1038,6 +1039,7 @@ _cairo_pdf_operators_add_glyph (cairo_pdf_operators_t *pdf_operators
pdf_operators->glyphs[pdf_operators->num_glyphs].x_position = x_position;
pdf_operators->glyphs[pdf_operators->num_glyphs].glyph_index = glyph->subset_glyph_index;
pdf_operators->glyphs[pdf_operators->num_glyphs].x_advance = x;
+ pdf_operators->glyph_buf_x_pos += x;
pdf_operators->num_glyphs++;
if (pdf_operators->num_glyphs == PDF_GLYPH_BUFFER_SIZE)
return _cairo_pdf_operators_flush_glyphs (pdf_operators);
@@ -1062,6 +1064,7 @@ _cairo_pdf_operators_set_text_matrix (cairo_pdf_operators_t *pdf_operators,
pdf_operators->text_matrix = *matrix;
pdf_operators->cur_x = 0;
pdf_operators->cur_y = 0;
+ pdf_operators->glyph_buf_x_pos = 0;
_cairo_output_stream_printf (pdf_operators->stream,
"%f %f %f %f %f %f Tm\n",
pdf_operators->text_matrix.xx,
@@ -1117,6 +1120,7 @@ _cairo_pdf_operators_set_text_position (cairo_pdf_operators_t *pdf_operators,
translate.y0);
pdf_operators->cur_x = 0;
pdf_operators->cur_y = 0;
+ pdf_operators->glyph_buf_x_pos = 0;
pdf_operators->cairo_to_pdftext = pdf_operators->text_matrix;
status = cairo_matrix_invert (&pdf_operators->cairo_to_pdftext);
@@ -1167,6 +1171,7 @@ _cairo_pdf_operators_begin_text (cairo_pdf_operators_t *pdf_operators)
pdf_operators->in_text_object = TRUE;
pdf_operators->num_glyphs = 0;
+ pdf_operators->glyph_buf_x_pos = 0;
return _cairo_output_stream_get_status (pdf_operators->stream);
}
@@ -1271,7 +1276,7 @@ _cairo_pdf_operators_emit_glyph (cairo_pdf_operators_t *pdf_operator
* PDF consumers that do not handle very large position
* adjustments in TJ.
*/
- if (fabs(x - pdf_operators->cur_x) > 10 ||
+ if (fabs(x - pdf_operators->glyph_buf_x_pos) > 10 ||
fabs(y - pdf_operators->cur_y) > GLYPH_POSITION_TOLERANCE)
{
status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
commit af3b550bc186361a0b6a779df0fc57799c3f163d
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 1 18:07:01 2010 +0930
PDF: Add support for latin subsets
Add support for Type 1 and TrueType latin subsets.
CFF latin subsets are not yet implemented.
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index a4a434f..48cab14 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -2011,6 +2011,26 @@ _cairo_cff_subset_fini (cairo_cff_subset_t *subset)
free (subset->data);
}
+cairo_bool_t
+_cairo_cff_scaled_font_is_cff (cairo_scaled_font_t *scaled_font)
+{
+ const cairo_scaled_font_backend_t *backend;
+ cairo_status_t status;
+ unsigned long data_length;
+
+ backend = scaled_font->backend;
+ if (!backend->load_truetype_table)
+ return FALSE;
+
+ data_length = 0;
+ status = backend->load_truetype_table(scaled_font,
+ TT_TAG_CFF, 0, NULL, &data_length);
+ if (status)
+ return FALSE;;
+
+ return TRUE;
+}
+
static cairo_int_status_t
_cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset,
cairo_cff_font_t **font_return,
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index c60e636..3265312 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -357,6 +357,8 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
goto BAIL1;
}
+ _cairo_scaled_font_subsets_enable_latin_subset (surface->font_subsets, TRUE);
+
surface->next_available_resource.id = 1;
surface->pages_resource = _cairo_pdf_surface_new_object (surface);
if (surface->pages_resource.id == 0) {
@@ -4069,7 +4071,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
cairo_pdf_font_t font;
cairo_status_t status;
unsigned long length;
- unsigned int i;
+ unsigned int i, last_glyph;
char tag[10];
_create_font_subset_tag (font_subset, subset->base_font, tag);
@@ -4105,6 +4107,15 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
if (_cairo_status_is_error (status))
return status;
+ if (font_subset->is_latin) {
+ /* find last glyph used */
+ for (i = 255; i >= 32; i--)
+ if (font_subset->latin_to_subset_glyph_index[i] > 0)
+ break;
+
+ last_glyph = i;
+ }
+
descriptor = _cairo_pdf_surface_new_object (surface);
if (descriptor.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -4113,7 +4124,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
"%d 0 obj\n"
"<< /Type /FontDescriptor\n"
" /FontName /%s+%s\n"
- " /Flags 4\n"
+ " /Flags %d\n"
" /FontBBox [ %ld %ld %ld %ld ]\n"
" /ItalicAngle 0\n"
" /Ascent %ld\n"
@@ -4127,6 +4138,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
descriptor.id,
tag,
subset->base_font,
+ font_subset->is_latin ? 32 : 4,
(long)(subset->x_min*PDF_UNITS_PER_EM),
(long)(subset->y_min*PDF_UNITS_PER_EM),
(long)(subset->x_max*PDF_UNITS_PER_EM),
@@ -4142,20 +4154,34 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
"<< /Type /Font\n"
" /Subtype /Type1\n"
" /BaseFont /%s+%s\n"
- " /FirstChar 0\n"
+ " /FirstChar %d\n"
" /LastChar %d\n"
" /FontDescriptor %d 0 R\n"
" /Widths [",
subset_resource.id,
tag,
subset->base_font,
- font_subset->num_glyphs - 1,
+ font_subset->is_latin ? 32 : 0,
+ font_subset->is_latin ? last_glyph : font_subset->num_glyphs - 1,
descriptor.id);
- for (i = 0; i < font_subset->num_glyphs; i++)
- _cairo_output_stream_printf (surface->output,
- " %ld",
- (long)(subset->widths[i]*PDF_UNITS_PER_EM));
+ if (font_subset->is_latin) {
+ for (i = 32; i < last_glyph + 1; i++) {
+ int glyph = font_subset->latin_to_subset_glyph_index[i];
+ if (glyph > 0) {
+ _cairo_output_stream_printf (surface->output,
+ " %ld",
+ (long)(subset->widths[glyph]*PDF_UNITS_PER_EM));
+ } else {
+ _cairo_output_stream_printf (surface->output, " 0");
+ }
+ }
+ } else {
+ for (i = 0; i < font_subset->num_glyphs; i++)
+ _cairo_output_stream_printf (surface->output,
+ " %ld",
+ (long)(subset->widths[i]*PDF_UNITS_PER_EM));
+ }
_cairo_output_stream_printf (surface->output,
" ]\n");
@@ -4226,7 +4252,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
cairo_status_t status;
cairo_pdf_font_t font;
cairo_truetype_subset_t subset;
- unsigned int i;
+ unsigned int i, last_glyph;
char tag[10];
subset_resource = _cairo_pdf_surface_get_font_resource (surface,
@@ -4289,7 +4315,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
}
_cairo_output_stream_printf (surface->output,
- " /Flags 4\n"
+ " /Flags %d\n"
" /FontBBox [ %ld %ld %ld %ld ]\n"
" /ItalicAngle 0\n"
" /Ascent %ld\n"
@@ -4300,6 +4326,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
" /FontFile2 %u 0 R\n"
">>\n"
"endobj\n",
+ font_subset->is_latin ? 32 : 4,
(long)(subset.x_min*PDF_UNITS_PER_EM),
(long)(subset.y_min*PDF_UNITS_PER_EM),
(long)(subset.x_max*PDF_UNITS_PER_EM),
@@ -4309,60 +4336,108 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
(long)(subset.y_max*PDF_UNITS_PER_EM),
stream.id);
- cidfont_dict = _cairo_pdf_surface_new_object (surface);
- if (cidfont_dict.id == 0) {
- _cairo_truetype_subset_fini (&subset);
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- }
+ if (font_subset->is_latin) {
+ /* find last glyph used */
+ for (i = 255; i >= 32; i--)
+ if (font_subset->latin_to_subset_glyph_index[i] > 0)
+ break;
- _cairo_output_stream_printf (surface->output,
- "%d 0 obj\n"
- "<< /Type /Font\n"
- " /Subtype /CIDFontType2\n"
- " /BaseFont /%s+%s\n"
- " /CIDSystemInfo\n"
- " << /Registry (Adobe)\n"
- " /Ordering (Identity)\n"
- " /Supplement 0\n"
- " >>\n"
- " /FontDescriptor %d 0 R\n"
- " /W [0 [",
- cidfont_dict.id,
- tag,
- subset.ps_name,
- descriptor.id);
+ last_glyph = i;
+ _cairo_pdf_surface_update_object (surface, subset_resource);
+ _cairo_output_stream_printf (surface->output,
+ "%d 0 obj\r\n"
+ "<< /Type /Font\n"
+ " /Subtype /TrueType\n"
+ " /BaseFont /%s+%s\n"
+ " /FirstChar 32\n"
+ " /LastChar %d\n"
+ " /FontDescriptor %d 0 R\n"
+ " /Encoding /WinAnsiEncoding\n"
+ " /Widths [",
+ subset_resource.id,
+ tag,
+ subset.ps_name,
+ last_glyph,
+ descriptor.id);
+
+ for (i = 32; i < last_glyph + 1; i++) {
+ int glyph = font_subset->latin_to_subset_glyph_index[i];
+ if (glyph > 0) {
+ _cairo_output_stream_printf (surface->output,
+ " %ld",
+ (long)(subset.widths[glyph]*PDF_UNITS_PER_EM));
+ } else {
+ _cairo_output_stream_printf (surface->output, " 0");
+ }
+ }
- for (i = 0; i < font_subset->num_glyphs; i++)
- _cairo_output_stream_printf (surface->output,
- " %ld",
- (long)(subset.widths[i]*PDF_UNITS_PER_EM));
+ _cairo_output_stream_printf (surface->output,
+ " ]\n");
- _cairo_output_stream_printf (surface->output,
- " ]]\n"
- ">>\n"
- "endobj\n");
+ if (to_unicode_stream.id != 0)
+ _cairo_output_stream_printf (surface->output,
+ " /ToUnicode %d 0 R\n",
+ to_unicode_stream.id);
- _cairo_pdf_surface_update_object (surface, subset_resource);
- _cairo_output_stream_printf (surface->output,
- "%d 0 obj\n"
- "<< /Type /Font\n"
- " /Subtype /Type0\n"
- " /BaseFont /%s+%s\n"
- " /Encoding /Identity-H\n"
- " /DescendantFonts [ %d 0 R]\n",
- subset_resource.id,
- tag,
- subset.ps_name,
- cidfont_dict.id);
+ _cairo_output_stream_printf (surface->output,
+ ">>\n"
+ "endobj\n");
+ } else {
+ cidfont_dict = _cairo_pdf_surface_new_object (surface);
+ if (cidfont_dict.id == 0) {
+ _cairo_truetype_subset_fini (&subset);
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
- if (to_unicode_stream.id != 0)
- _cairo_output_stream_printf (surface->output,
- " /ToUnicode %d 0 R\n",
- to_unicode_stream.id);
+ _cairo_output_stream_printf (surface->output,
+ "%d 0 obj\n"
+ "<< /Type /Font\n"
+ " /Subtype /CIDFontType2\n"
+ " /BaseFont /%s+%s\n"
+ " /CIDSystemInfo\n"
+ " << /Registry (Adobe)\n"
+ " /Ordering (Identity)\n"
+ " /Supplement 0\n"
+ " >>\n"
+ " /FontDescriptor %d 0 R\n"
+ " /W [0 [",
+ cidfont_dict.id,
+ tag,
+ subset.ps_name,
+ descriptor.id);
+
+ for (i = 0; i < font_subset->num_glyphs; i++)
+ _cairo_output_stream_printf (surface->output,
+ " %ld",
+ (long)(subset.widths[i]*PDF_UNITS_PER_EM));
- _cairo_output_stream_printf (surface->output,
- ">>\n"
- "endobj\n");
+ _cairo_output_stream_printf (surface->output,
+ " ]]\n"
+ ">>\n"
+ "endobj\n");
+
+ _cairo_pdf_surface_update_object (surface, subset_resource);
+ _cairo_output_stream_printf (surface->output,
+ "%d 0 obj\n"
+ "<< /Type /Font\n"
+ " /Subtype /Type0\n"
+ " /BaseFont /%s+%s\n"
+ " /Encoding /Identity-H\n"
+ " /DescendantFonts [ %d 0 R]\n",
+ subset_resource.id,
+ tag,
+ subset.ps_name,
+ cidfont_dict.id);
+
+ if (to_unicode_stream.id != 0)
+ _cairo_output_stream_printf (surface->output,
+ " /ToUnicode %d 0 R\n",
+ to_unicode_stream.id);
+
+ _cairo_output_stream_printf (surface->output,
+ ">>\n"
+ "endobj\n");
+ }
font.font_id = font_subset->font_id;
font.subset_id = font_subset->subset_id;
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index 7c5756f..44b037a 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -387,6 +387,15 @@ cairo_private void
_cairo_cff_subset_fini (cairo_cff_subset_t *cff_subset);
/**
+ * _cairo_cff_scaled_font_is_cff:
+ * @scaled_font: a #cairo_scaled_font_t
+ *
+ * Return %TRUE if @scaled_font is a CFF font, otherwise return %FALSE.
+ **/
+cairo_bool_t
+_cairo_cff_scaled_font_is_cff (cairo_scaled_font_t *scaled_font);
+
+/**
* _cairo_cff_fallback_init:
* @cff_subset: a #cairo_cff_subset_t to initialize
* @font_subset: the #cairo_scaled_font_subset_t to initialize from
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 677bd5a..79a778f 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -70,6 +70,7 @@ typedef struct _cairo_sub_font {
cairo_bool_t is_scaled;
cairo_bool_t is_composite;
cairo_bool_t is_user;
+ cairo_bool_t use_latin_subset;
cairo_scaled_font_subsets_t *parent;
cairo_scaled_font_t *scaled_font;
unsigned int font_id;
@@ -294,7 +295,11 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
sub_font->scaled_font = scaled_font;
sub_font->font_id = font_id;
- if (parent->use_latin_subset)
+ sub_font->use_latin_subset = parent->use_latin_subset;
+ if (_cairo_cff_scaled_font_is_cff (scaled_font))
+ sub_font->use_latin_subset = FALSE; /* CFF latin subsets are NYI */
+
+ if (sub_font->use_latin_subset)
sub_font->current_subset = 1; /* reserve subset 0 for latin glyphs */
else
sub_font->current_subset = 0;
@@ -616,7 +621,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
* create a separate subset just for the .notdef glyph.
*/
is_latin = FALSE;
- if (sub_font->parent->use_latin_subset &&
+ if (sub_font->use_latin_subset &&
(! _cairo_font_face_is_user (sub_font->scaled_font->font_face)))
{
latin_character = _cairo_unicode_to_winansi (font_unicode);
@@ -702,7 +707,7 @@ _cairo_sub_font_collect (void *entry, void *closure)
subset.glyph_names = NULL;
subset.is_latin = FALSE;
- if (sub_font->parent->use_latin_subset && i == 0) {
+ if (sub_font->use_latin_subset && i == 0) {
subset.is_latin = TRUE;
subset.latin_to_subset_glyph_index = collection->latin_to_subset_glyph_index;
} else {
commit 85c25d79f7e77ae35a68b9444609aef8d5397011
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 1 18:05:34 2010 +0930
TrueType subsetting: embed a cmap for latin subsets
To support latin subsets in PDF, TrueType fonts require a cmap to map
unicode to glyph indices for all characters in the winansi encoding.
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index 2a8cd77..7c5756f 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -460,6 +460,9 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
cairo_private void
_cairo_truetype_subset_fini (cairo_truetype_subset_t *truetype_subset);
+cairo_private int
+_cairo_unicode_to_winansi (unsigned long unicode);
+
cairo_private const char *
_cairo_winansi_to_glyphname (int glyph);
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 24a700a..677bd5a 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -343,7 +343,8 @@ static unsigned int _winansi_0x80_to_0x9f[] = {
0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178
};
-static int _unicode_to_winansi (unsigned long unicode)
+int
+_cairo_unicode_to_winansi (unsigned long unicode)
{
int i;
@@ -618,7 +619,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
if (sub_font->parent->use_latin_subset &&
(! _cairo_font_face_is_user (sub_font->scaled_font->font_face)))
{
- latin_character = _unicode_to_winansi (font_unicode);
+ latin_character = _cairo_unicode_to_winansi (font_unicode);
if (latin_character > 0 ||
(latin_character == 0 && sub_font->num_glyphs_in_latin_subset > 0))
{
@@ -1184,7 +1185,7 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
}
if (utf16_len == 1) {
- int ch = _unicode_to_winansi (utf16[0]);
+ int ch = _cairo_unicode_to_winansi (utf16[0]);
if (ch > 0)
strncpy (buf, _cairo_winansi_to_glyphname (ch), sizeof (buf));
else
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 9bf2f8f..b774bd2 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -393,51 +393,98 @@ cairo_truetype_font_check_boundary (cairo_truetype_font_t *font,
return CAIRO_STATUS_SUCCESS;
}
+typedef struct _cmap_unicode_range {
+ unsigned int start;
+ unsigned int end;
+} cmap_unicode_range_t;
+
+static cmap_unicode_range_t winansi_unicode_ranges[] = {
+ { 0x0020, 0x007f },
+ { 0x00a0, 0x00ff },
+ { 0x0152, 0x0153 },
+ { 0x0178, 0x0178 },
+ { 0x017d, 0x017e },
+ { 0x0192, 0x0192 },
+ { 0x02c6, 0x02c6 },
+ { 0x02dc, 0x02dc },
+ { 0x2013, 0x2026 },
+ { 0x2030, 0x2030 },
+ { 0x2039, 0x203a },
+ { 0x2122, 0x2122 },
+};
+
static cairo_status_t
cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font,
unsigned long tag)
{
- unsigned int i;
+ int i;
+ unsigned int j;
+ int range_offset;
+ int num_ranges;
+ int entry_selector;
+ int length;
+
+ num_ranges = ARRAY_LENGTH (winansi_unicode_ranges);
+
+ length = 16 + (num_ranges + 1)*8;
+ for (i = 0; i < num_ranges; i++)
+ length += (winansi_unicode_ranges[i].end - winansi_unicode_ranges[i].start + 1)*2;
+
+ entry_selector = 0;
+ while ((1 << entry_selector) <= (num_ranges + 1))
+ entry_selector++;
+
+ entry_selector--;
cairo_truetype_font_write_be16 (font, 0); /* Table version */
- cairo_truetype_font_write_be16 (font, 2); /* Num tables */
+ cairo_truetype_font_write_be16 (font, 1); /* Num tables */
cairo_truetype_font_write_be16 (font, 3); /* Platform */
- cairo_truetype_font_write_be16 (font, 0); /* Encoding */
- cairo_truetype_font_write_be32 (font, 20); /* Offset to start of table */
+ cairo_truetype_font_write_be16 (font, 1); /* Encoding */
+ cairo_truetype_font_write_be32 (font, 12); /* Offset to start of table */
- cairo_truetype_font_write_be16 (font, 1); /* Platform */
- cairo_truetype_font_write_be16 (font, 0); /* Encoding */
- cairo_truetype_font_write_be32 (font, 52); /* Offset to start of table */
-
- /* Output a format 4 encoding table. */
+ /* Output a format 4 encoding table for the winansi encoding */
cairo_truetype_font_write_be16 (font, 4); /* Format */
- cairo_truetype_font_write_be16 (font, 32); /* Length */
+ cairo_truetype_font_write_be16 (font, length); /* Length */
cairo_truetype_font_write_be16 (font, 0); /* Version */
- cairo_truetype_font_write_be16 (font, 4); /* 2*segcount */
- cairo_truetype_font_write_be16 (font, 4); /* searchrange */
- cairo_truetype_font_write_be16 (font, 1); /* entry selector */
- cairo_truetype_font_write_be16 (font, 0); /* rangeshift */
- cairo_truetype_font_write_be16 (font, 0xf000 + font->base.num_glyphs - 1); /* end count[0] */
- cairo_truetype_font_write_be16 (font, 0xffff); /* end count[1] */
+ cairo_truetype_font_write_be16 (font, num_ranges*2 + 2); /* 2*segcount */
+ cairo_truetype_font_write_be16 (font, (1 << (entry_selector + 1))); /* searchrange */
+ cairo_truetype_font_write_be16 (font, entry_selector); /* entry selector */
+ cairo_truetype_font_write_be16 (font, num_ranges*2 + 2 - (1 << (entry_selector + 1))); /* rangeshift */
+ for (i = 0; i < num_ranges; i++)
+ cairo_truetype_font_write_be16 (font, winansi_unicode_ranges[i].end); /* end count[] */
+ cairo_truetype_font_write_be16 (font, 0xffff); /* end count[] */
+
cairo_truetype_font_write_be16 (font, 0); /* reserved */
- cairo_truetype_font_write_be16 (font, 0xf000); /* startCode[0] */
- cairo_truetype_font_write_be16 (font, 0xffff); /* startCode[1] */
- cairo_truetype_font_write_be16 (font, 0x1000); /* delta[0] */
- cairo_truetype_font_write_be16 (font, 1); /* delta[1] */
- cairo_truetype_font_write_be16 (font, 0); /* rangeOffset[0] */
- cairo_truetype_font_write_be16 (font, 0); /* rangeOffset[1] */
-
- /* Output a format 6 encoding table. */
-
- cairo_truetype_font_write_be16 (font, 6);
- cairo_truetype_font_write_be16 (font, 10 + 2 * font->base.num_glyphs);
- cairo_truetype_font_write_be16 (font, 0);
- cairo_truetype_font_write_be16 (font, 0); /* First character */
- cairo_truetype_font_write_be16 (font, font->base.num_glyphs);
- for (i = 0; i < font->base.num_glyphs; i++)
- cairo_truetype_font_write_be16 (font, i);
+
+ for (i = 0; i < num_ranges; i++)
+ cairo_truetype_font_write_be16 (font, winansi_unicode_ranges[i].start); /* startCode[] */
+ cairo_truetype_font_write_be16 (font, 0xffff); /* startCode[] */
+
+ for (i = 0; i < num_ranges; i++)
+ cairo_truetype_font_write_be16 (font, 0x0000); /* delta[] */
+ cairo_truetype_font_write_be16 (font, 1); /* delta[] */
+
+ range_offset = num_ranges*2 + 2;
+ for (i = 0; i < num_ranges; i++) {
+ cairo_truetype_font_write_be16 (font, range_offset); /* rangeOffset[] */
+ range_offset += (winansi_unicode_ranges[i].end - winansi_unicode_ranges[i].start + 1)*2 - 2;
+ }
+ cairo_truetype_font_write_be16 (font, 0); /* rangeOffset[] */
+
+ for (i = 0; i < num_ranges; i++) {
+ for (j = winansi_unicode_ranges[i].start; j < winansi_unicode_ranges[i].end + 1; j++) {
+ int ch = _cairo_unicode_to_winansi (j);
+ int glyph;
+
+ if (ch > 0)
+ glyph = font->scaled_font_subset->latin_to_subset_glyph_index[ch];
+ else
+ glyph = 0;
+ cairo_truetype_font_write_be16 (font, glyph);
+ }
+ }
return font->status;
}
@@ -985,8 +1032,9 @@ cairo_truetype_font_add_truetype_table (cairo_truetype_font_t *font,
* The tables in the table directory must be listed in alphabetical
* order. The "cvt", "fpgm", and "prep" are optional tables. They
* will only be embedded in the subset if they exist in the source
- * font. The pos parameter of cairo_truetype_font_add_truetype_table()
- * specifies the position of the table in the table directory.
+ * font. "cmap" is only embedded for latin fonts. The pos parameter of
+ * cairo_truetype_font_add_truetype_table() specifies the position of
+ * the table in the table directory.
*/
static void
cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
@@ -1016,7 +1064,9 @@ cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
has_prep = TRUE;
font->num_tables = 0;
- pos = 1;
+ pos = 0;
+ if (font->scaled_font_subset->is_latin)
+ pos++;
if (has_cvt)
pos++;
if (has_fpgm)
@@ -1024,7 +1074,8 @@ 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;
- cairo_truetype_font_add_truetype_table (font, TT_TAG_cmap, cairo_truetype_font_write_cmap_table, pos++);
+ if (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++);
if (has_fpgm)
commit 7c268bc8382350ab803eecb898d4650999a3a6bb
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 1 18:01:07 2010 +0930
PS: Enable support for latin subsets
Make PS TrueType embedding use the winansi glyph mapping for latin subsets.
Enable use of latin subsets in PS.
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index c73214e..1c5d7a9 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -426,14 +426,29 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
/* FIXME: Figure out how subset->x_max etc maps to the /FontBBox */
- for (i = 1; i < font_subset->num_glyphs; i++) {
- if (font_subset->glyph_names != NULL) {
- _cairo_output_stream_printf (surface->final_stream,
- "Encoding %d /%s put\n",
- i, font_subset->glyph_names[i]);
- } else {
- _cairo_output_stream_printf (surface->final_stream,
- "Encoding %d /g%d put\n", i, i);
+ if (font_subset->is_latin) {
+ for (i = 1; i < 256; i++) {
+ if (font_subset->latin_to_subset_glyph_index[i] > 0) {
+ if (font_subset->glyph_names != NULL) {
+ _cairo_output_stream_printf (surface->final_stream,
+ "Encoding %d /%s put\n",
+ i, font_subset->glyph_names[font_subset->latin_to_subset_glyph_index[i]]);
+ } else {
+ _cairo_output_stream_printf (surface->final_stream,
+ "Encoding %d /g%ld put\n", i, font_subset->latin_to_subset_glyph_index[i]);
+ }
+ }
+ }
+ } else {
+ for (i = 1; i < font_subset->num_glyphs; i++) {
+ if (font_subset->glyph_names != NULL) {
+ _cairo_output_stream_printf (surface->final_stream,
+ "Encoding %d /%s put\n",
+ i, font_subset->glyph_names[i]);
+ } else {
+ _cairo_output_stream_printf (surface->final_stream,
+ "Encoding %d /g%d put\n", i, i);
+ }
}
}
@@ -956,6 +971,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
goto CLEANUP_OUTPUT_STREAM;
}
+ _cairo_scaled_font_subsets_enable_latin_subset (surface->font_subsets, TRUE);
surface->has_creation_date = FALSE;
surface->eps = FALSE;
surface->ps_level = CAIRO_PS_LEVEL_3;
commit 52f3db92a747eb694b94f28d6862abd573f3b378
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 1 17:58:40 2010 +0930
Type 1 fallback: add support for latin subsets
For latin subsets the /Encoding array maps the latin encoding to the
font glyphs.
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index b93c423..c2d0fa6 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -514,12 +514,27 @@ cairo_type1_font_write_header (cairo_type1_font_t *font,
"} readonly def\n"
"/Encoding 256 array\n"
"0 1 255 {1 index exch /.notdef put} for\n");
- for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
- if (font->scaled_font_subset->glyph_names != NULL) {
- _cairo_output_stream_printf (font->output, "dup %d /%s put\n",
- i, font->scaled_font_subset->glyph_names[i]);
- } else {
- _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i);
+ if (font->scaled_font_subset->is_latin) {
+ for (i = 1; i < 256; i++) {
+ int subset_glyph = font->scaled_font_subset->latin_to_subset_glyph_index[i];
+
+ if (subset_glyph > 0) {
+ if (font->scaled_font_subset->glyph_names != NULL) {
+ _cairo_output_stream_printf (font->output, "dup %d /%s put\n",
+ i, font->scaled_font_subset->glyph_names[subset_glyph]);
+ } else {
+ _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, subset_glyph);
+ }
+ }
+ }
+ } else {
+ for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
+ if (font->scaled_font_subset->glyph_names != NULL) {
+ _cairo_output_stream_printf (font->output, "dup %d /%s put\n",
+ i, font->scaled_font_subset->glyph_names[i]);
+ } else {
+ _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i);
+ }
}
}
_cairo_output_stream_printf (font->output,
commit 4a0e5b7ced989b2c1a17757ba17142eb55e3924d
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 1 17:58:20 2010 +0930
Type 1 subsetting: add support for latin subsets
For latin subsets the /Encoding array maps the latin encoding to the
font glyphs.
diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index 636cc8b..9346951 100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -116,6 +116,7 @@ typedef struct _cairo_type1_font_subset {
static cairo_status_t
_cairo_type1_font_subset_init (cairo_type1_font_subset_t *font,
cairo_unscaled_font_t *unscaled_font,
+ cairo_scaled_font_subset_t *scaled_font_subset,
cairo_bool_t hex_encode)
{
cairo_ft_unscaled_font_t *ft_unscaled_font;
@@ -144,6 +145,7 @@ _cairo_type1_font_subset_init (cairo_type1_font_subset_t *font,
#endif
memset (font, 0, sizeof (*font));
+ font->scaled_font_subset = scaled_font_subset;
font->base.unscaled_font = _cairo_unscaled_font_reference (unscaled_font);
font->base.num_glyphs = face->num_glyphs;
font->base.x_min = face->bbox.xMin;
@@ -391,13 +393,27 @@ cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font,
_cairo_output_stream_printf (font->output,
"/Encoding 256 array\n"
"0 1 255 {1 index exch /.notdef put} for\n");
- for (i = 1; i < font->base.num_glyphs; i++) {
- if (font->glyphs[i].subset_index < 0)
- continue;
- _cairo_output_stream_printf (font->output,
- "dup %d /%s put\n",
- font->glyphs[i].subset_index,
- font->glyphs[i].name);
+ if (font->scaled_font_subset->is_latin) {
+ for (i = 1; i < 256; i++) {
+ int subset_glyph = font->scaled_font_subset->latin_to_subset_glyph_index[i];
+ int parent_glyph = font->scaled_font_subset->glyphs[subset_glyph];
+
+ if (subset_glyph > 0) {
+ _cairo_output_stream_printf (font->output,
+ "dup %d /%s put\n",
+ i,
+ font->glyphs[parent_glyph].name);
+ }
+ }
+ } else {
+ for (i = 1; i < font->base.num_glyphs; i++) {
+ if (font->glyphs[i].subset_index < 0)
+ continue;
+ _cairo_output_stream_printf (font->output,
+ "dup %d /%s put\n",
+ font->glyphs[i].subset_index,
+ font->glyphs[i].name);
+ }
}
_cairo_output_stream_printf (font->output, "readonly def");
@@ -1415,7 +1431,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font_subset->scaled_font);
- status = _cairo_type1_font_subset_init (&font, unscaled_font, hex_encode);
+ status = _cairo_type1_font_subset_init (&font, unscaled_font, scaled_font_subset, hex_encode);
if (unlikely (status))
return status;
commit 01ee091ee98bc0544d9a3d5665cdecddd8f368cc
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 1 17:57:43 2010 +0930
Add winansi glyph names
for the PS backend and Type 1 subsetters to use with latin fonts.
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index d119597..2a8cd77 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -460,7 +460,8 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
cairo_private void
_cairo_truetype_subset_fini (cairo_truetype_subset_t *truetype_subset);
-
+cairo_private const char *
+_cairo_winansi_to_glyphname (int glyph);
typedef struct _cairo_type1_subset {
char *base_font;
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 3478351..24a700a 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -1184,7 +1184,12 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
}
if (utf16_len == 1) {
- snprintf (buf, sizeof (buf), "uni%04X", (int) utf16[0]);
+ int ch = _unicode_to_winansi (utf16[0]);
+ if (ch > 0)
+ strncpy (buf, _cairo_winansi_to_glyphname (ch), sizeof (buf));
+ else
+ snprintf (buf, sizeof (buf), "uni%04X", (int) utf16[0]);
+
_cairo_string_init_key (&key, buf);
entry = _cairo_hash_table_lookup (names, &key.base);
if (entry != NULL)
diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index 9c0a2cf..636cc8b 100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -804,6 +804,98 @@ static const int16_t ps_standard_encoding_offset[256] = {
#define ps_standard_encoding(index) ((index) ? ps_standard_encoding_symbol+ps_standard_encoding_offset[(index)] : NULL)
+/* TODO: Merge these names into ps_standard_encoding_symbol (with a
+ * separate winansi_encoding_offset table) as most of the names are
+ * the same. */
+static const char *winansi_encoding[256] = {
+ /* 0 */
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ /* 16 */
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ /* 32 */
+ "space", "exclam", "quotedbl", "numbersign",
+ "dollar", "percent", "ampersand", "quoteright",
+ "parenleft", "parenright", "asterisk", "plus",
+ "comma", "hyphen", "period", "slash",
+ /* 48 */
+ "zero", "one", "two", "three",
+ "four", "five", "six", "seven",
+ "eight", "nine", "colon", "semicolon",
+ "less", "equal", "greater", "question",
+ /* 64 */
+ "at", "A", "B", "C",
+ "D", "E", "F", "G",
+ "H", "I", "J", "K",
+ "L", "M", "N", "O",
+ /* 80 */
+ "P", "Q", "R", "S",
+ "T", "U", "V", "W",
+ "X", "Y", "Z", "bracketleft",
+ "backslash", "bracketright", "asciicircum", "underscore",
+ /* 96 */
+ "quoteleft", "a", "b", "c",
+ "d", "e", "f", "g",
+ "h", "i", "j", "k",
+ "l", "m", "n", "o",
+ /* 112 */
+ "p", "q", "r", "s",
+ "t", "u", "v", "w",
+ "x", "y", "z", "braceleft",
+ "bar", "braceright", "asciitilde", NULL,
+ /* 128 */
+ "Euro", NULL, "quotesinglbase","florin",
+ "quotedblbase", "ellipsis", "dagger", "daggerdbl",
+ "circumflex", "perthousand", "Scaron", "guilsinglleft",
+ "OE", "bullet", "Zcaron", NULL,
+ /* 144 */
+ NULL, "quoteleft", "quoteright", "quotedblleft",
+ "quotedblright","bullet", "endash", "emdash",
+ "tilde", "trademark", "scaron", "guilsinglright",
+ "oe", "bullet", "zcaron", "Ydieresis",
+ /* 160 */
+ "space", "exclamdown", "cent", "sterling",
+ "currency", "yen", "brokenbar", "section",
+ "dieresis", "copyright", "ordfeminine", "guillemotleft",
+ "logicalnot", "hyphen", "registered", "macron",
+ /* 176 */
+ "degree", "plusminus", "twosuperior", "threesuperior",
+ "acute", "mu", "paragraph", "periodcentered",
+ "cedilla", "onesuperior", "ordmasculine", "guillemotright",
+ "onequarter", "onehalf", "threequarters","questiondown",
+ /* 192 */
+ "Agrave", "Aacute", "Acircumflex", "Atilde",
+ "Adieresis", "Aring", "AE", "Ccedilla",
+ "Egrave", "Eacute", "Ecircumflex", "Edieresis",
+ "Igrave", "Iacute", "Icircumflex", "Idieresis",
+ /* 208 */
+ "Eth", "Ntilde", "Ograve", "Oacute",
+ "Ocircumflex", "Otilde", "Odieresis", "multiply",
+ "Oslash", "Ugrave", "Uacute", "Ucircumflex",
+ "Udieresis", "Yacute", "Thorn", "germandbls",
+ /* 224 */
+ "agrave", "aacute", "acircumflex", "atilde",
+ "adieresis", "aring", "ae", "ccedilla",
+ "egrave", "eacute", "ecircumflex", "edieresis",
+ "igrave", "iacute", "icircumflex", "idieresis",
+ /* 240 */
+ "eth", "ntilde", "ograve", "oacute",
+ "ocircumflex", "otilde", "odieresis", "divide",
+ "oslash", "ugrave", "uacute", "ucircumflex",
+ "udieresis", "yacute", "thorn", "ydieresis"
+};
+
+const char *
+_cairo_winansi_to_glyphname (int glyph)
+{
+ return winansi_encoding[glyph];
+}
+
static cairo_status_t
use_standard_encoding_glyph (cairo_type1_font_subset_t *font, int index)
{
commit e62891cd8f27b62c3ee04d822524c9cee69a2e62
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 1 17:55:53 2010 +0930
Return latin to glyph mapping in cairo_scaled_font_subset_t
so that font subsetters can include the latin to glyph encoding in the
subsetted font.
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 9d8d6c1..3478351 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -120,6 +120,7 @@ typedef struct _cairo_sub_font_collection {
unsigned long *glyphs; /* scaled_font_glyph_index */
char **utf8;
unsigned int glyphs_size;
+ unsigned long *latin_to_subset_glyph_index;
unsigned int max_glyph;
unsigned int num_glyphs;
@@ -230,6 +231,9 @@ _cairo_sub_font_glyph_collect (void *entry, void *closure)
collection->glyphs[subset_glyph_index] = scaled_font_glyph_index;
collection->utf8[subset_glyph_index] = sub_font_glyph->utf8;
+ if (sub_font_glyph->is_latin)
+ collection->latin_to_subset_glyph_index[sub_font_glyph->latin_character] = subset_glyph_index;
+
if (subset_glyph_index > collection->max_glyph)
collection->max_glyph = subset_glyph_index;
@@ -674,6 +678,7 @@ _cairo_sub_font_collect (void *entry, void *closure)
collection->subset_id = i;
collection->num_glyphs = 0;
collection->max_glyph = 0;
+ memset (collection->latin_to_subset_glyph_index, 0, 256*sizeof(unsigned long));
_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
_cairo_sub_font_glyph_collect, collection);
@@ -694,6 +699,15 @@ _cairo_sub_font_collect (void *entry, void *closure)
subset.utf8 = collection->utf8;
subset.num_glyphs = collection->num_glyphs;
subset.glyph_names = NULL;
+
+ subset.is_latin = FALSE;
+ if (sub_font->parent->use_latin_subset && i == 0) {
+ subset.is_latin = TRUE;
+ subset.latin_to_subset_glyph_index = collection->latin_to_subset_glyph_index;
+ } else {
+ subset.latin_to_subset_glyph_index = NULL;
+ }
+
/* No need to check for out of memory here. If to_unicode is NULL, the PDF
* surface does not emit an ToUnicode stream */
subset.to_unicode = _cairo_malloc_ab (collection->num_glyphs, sizeof (unsigned long));
@@ -1005,11 +1019,16 @@ _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t
collection.glyphs = _cairo_malloc_ab (collection.glyphs_size, sizeof(unsigned long));
collection.utf8 = _cairo_malloc_ab (collection.glyphs_size, sizeof(char *));
- if (unlikely (collection.glyphs == NULL || collection.utf8 == NULL)) {
+ collection.latin_to_subset_glyph_index = _cairo_malloc_ab (256, sizeof(unsigned long));
+ if (unlikely (collection.glyphs == NULL ||
+ collection.utf8 == NULL ||
+ collection.latin_to_subset_glyph_index == NULL)) {
if (collection.glyphs != NULL)
free (collection.glyphs);
if (collection.utf8 != NULL)
free (collection.utf8);
+ if (collection.latin_to_subset_glyph_index != NULL)
+ free (collection.latin_to_subset_glyph_index);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -1031,6 +1050,7 @@ _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t
}
free (collection.utf8);
free (collection.glyphs);
+ free (collection.latin_to_subset_glyph_index);
return collection.status;
}
diff --git a/src/cairoint.h b/src/cairoint.h
index 500b2d9..d0ae66a 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -436,9 +436,11 @@ typedef struct _cairo_scaled_font_subset {
unsigned long *to_unicode;
char **utf8;
char **glyph_names;
+ unsigned long *latin_to_subset_glyph_index;
unsigned int num_glyphs;
cairo_bool_t is_composite;
cairo_bool_t is_scaled;
+ cairo_bool_t is_latin;
} cairo_scaled_font_subset_t;
struct _cairo_scaled_font_backend {
commit 807e690de4fda63a42a49a4342b563a6d54377ce
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 1 17:55:02 2010 +0930
pdf-operators: output (abc) style strings when font is latin
diff --git a/src/cairo-pdf-operators-private.h b/src/cairo-pdf-operators-private.h
index 95d4d53..1f5ee17 100644
--- a/src/cairo-pdf-operators-private.h
+++ b/src/cairo-pdf-operators-private.h
@@ -81,6 +81,7 @@ typedef struct _cairo_pdf_operators {
double cur_x; /* Current position in PDF text space (Tm in the PDF reference) */
double cur_y;
int hex_width;
+ cairo_bool_t is_latin;
int num_glyphs;
cairo_pdf_glyph_t glyphs[PDF_GLYPH_BUFFER_SIZE];
diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index 601011a..2d718ed 100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -880,6 +880,26 @@ _cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators,
operator);
}
+static void
+_cairo_pdf_operators_emit_glyph_index (cairo_pdf_operators_t *pdf_operators,
+ cairo_output_stream_t *stream,
+ unsigned int glyph)
+{
+ if (pdf_operators->is_latin) {
+ if (glyph == '(' || glyph == ')' || glyph == '\\')
+ _cairo_output_stream_printf (stream, "\\%c", glyph);
+ else if (glyph >= 0x20 && glyph <= 0x7e)
+ _cairo_output_stream_printf (stream, "%c", glyph);
+ else
+ _cairo_output_stream_printf (stream, "\\%03o", glyph);
+ } else {
+ _cairo_output_stream_printf (stream,
+ "%0*x",
+ pdf_operators->hex_width,
+ glyph);
+ }
+}
+
#define GLYPH_POSITION_TOLERANCE 0.001
/* Emit the string of glyphs using the 'Tj' operator. This requires
@@ -890,15 +910,14 @@ _cairo_pdf_operators_emit_glyph_string (cairo_pdf_operators_t *pdf_operators,
{
int i;
- _cairo_output_stream_printf (stream, "<");
+ _cairo_output_stream_printf (stream, "%s", pdf_operators->is_latin ? "(" : "<");
for (i = 0; i < pdf_operators->num_glyphs; i++) {
- _cairo_output_stream_printf (stream,
- "%0*x",
- pdf_operators->hex_width,
- pdf_operators->glyphs[i].glyph_index);
+ _cairo_pdf_operators_emit_glyph_index (pdf_operators,
+ stream,
+ pdf_operators->glyphs[i].glyph_index);
pdf_operators->cur_x += pdf_operators->glyphs[i].x_advance;
}
- _cairo_output_stream_printf (stream, ">Tj\n");
+ _cairo_output_stream_printf (stream, "%sTj\n", pdf_operators->is_latin ? ")" : ">");
return _cairo_output_stream_get_status (stream);
}
@@ -918,7 +937,7 @@ _cairo_pdf_operators_emit_glyph_string_with_positioning (
{
int i;
- _cairo_output_stream_printf (stream, "[<");
+ _cairo_output_stream_printf (stream, "[%s", pdf_operators->is_latin ? "(" : "<");
for (i = 0; i < pdf_operators->num_glyphs; i++) {
if (pdf_operators->glyphs[i].x_position != pdf_operators->cur_x)
{
@@ -934,10 +953,18 @@ _cairo_pdf_operators_emit_glyph_string_with_positioning (
* calculating subsequent deltas.
*/
rounded_delta = _cairo_lround (delta);
+ if (abs(rounded_delta) < 3)
+ rounded_delta = 0;
if (rounded_delta != 0) {
- _cairo_output_stream_printf (stream,
- ">%d<",
- rounded_delta);
+ if (pdf_operators->is_latin) {
+ _cairo_output_stream_printf (stream,
+ ")%d(",
+ rounded_delta);
+ } else {
+ _cairo_output_stream_printf (stream,
+ ">%d<",
+ rounded_delta);
+ }
}
/* Convert the rounded delta back to text
@@ -947,13 +974,12 @@ _cairo_pdf_operators_emit_glyph_string_with_positioning (
pdf_operators->cur_x += delta;
}
- _cairo_output_stream_printf (stream,
- "%0*x",
- pdf_operators->hex_width,
- pdf_operators->glyphs[i].glyph_index);
+ _cairo_pdf_operators_emit_glyph_index (pdf_operators,
+ stream,
+ pdf_operators->glyphs[i].glyph_index);
pdf_operators->cur_x += pdf_operators->glyphs[i].x_advance;
}
- _cairo_output_stream_printf (stream, ">]TJ\n");
+ _cairo_output_stream_printf (stream, "%s]TJ\n", pdf_operators->is_latin ? ")" : ">");
return _cairo_output_stream_get_status (stream);
}
@@ -1124,6 +1150,7 @@ _cairo_pdf_operators_set_font_subset (cairo_pdf_operators_t *pdf_ope
}
pdf_operators->font_id = subset_glyph->font_id;
pdf_operators->subset_id = subset_glyph->subset_id;
+ pdf_operators->is_latin = subset_glyph->is_latin;
if (subset_glyph->is_composite)
pdf_operators->hex_width = 4;
commit f1ca978032e973c4dc5cfa385074dea675a6c76d
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 1 17:53:11 2010 +0930
Add capability for font subsets to put latin glyphs in a separate subset
This is required to allow PDF/PS output to use "(this is ascii)" style
strings that can be post processed by applications like psfrag. It
will also reduce the file size when a large amount of latin text is
used due to the 8-bit encoding instead of the 16-bit used for CID
fonts.
The winansi encoding (CP1252) is used for the latin subset as this is
a standard PDF encoding. Some PDF readers have buggy support for non
standard PDF 8-bit encodings.
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index b165d9a..d119597 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -47,6 +47,7 @@ typedef struct _cairo_scaled_font_subsets_glyph {
unsigned int subset_glyph_index;
cairo_bool_t is_scaled;
cairo_bool_t is_composite;
+ cairo_bool_t is_latin;
double x_advance;
double y_advance;
cairo_bool_t utf8_is_mapped;
@@ -125,6 +126,18 @@ cairo_private void
_cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *font_subsets);
/**
+ * _cairo_scaled_font_subsets_enable_latin_subset:
+ * @font_subsets: a #cairo_scaled_font_subsets_t object to be destroyed
+ * @use_latin: a #cairo_bool_t indicating if a latin subset is to be used
+ *
+ * If enabled, all CP1252 characters will be placed in a separate
+ * 8-bit latin subset.
+ **/
+cairo_private void
+_cairo_scaled_font_subsets_enable_latin_subset (cairo_scaled_font_subsets_t *font_subsets,
+ cairo_bool_t use_latin);
+
+/**
* _cairo_scaled_font_subsets_map_glyph:
* @font_subsets: a #cairo_scaled_font_subsets_t
* @scaled_font: the font of the glyph to be mapped
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 01bc05b..9d8d6c1 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -76,6 +76,7 @@ typedef struct _cairo_sub_font {
int current_subset;
int num_glyphs_in_current_subset;
+ int num_glyphs_in_latin_subset;
int max_glyphs_per_subset;
cairo_hash_table_t *sub_font_glyphs;
@@ -84,6 +85,7 @@ typedef struct _cairo_sub_font {
struct _cairo_scaled_font_subsets {
cairo_subsets_type_t type;
+ cairo_bool_t use_latin_subset;
int max_glyphs_per_unscaled_subset_used;
cairo_hash_table_t *unscaled_sub_fonts;
@@ -106,6 +108,8 @@ typedef struct _cairo_sub_font_glyph {
double x_advance;
double y_advance;
+ cairo_bool_t is_latin;
+ int latin_character;
cairo_bool_t is_mapped;
uint32_t unicode;
char *utf8;
@@ -159,7 +163,11 @@ _cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index,
unsigned int subset_id,
unsigned int subset_glyph_index,
double x_advance,
- double y_advance)
+ double y_advance,
+ int latin_character,
+ uint32_t unicode,
+ char *utf8,
+ int utf8_len)
{
cairo_sub_font_glyph_t *sub_font_glyph;
@@ -174,10 +182,12 @@ _cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index,
sub_font_glyph->subset_glyph_index = subset_glyph_index;
sub_font_glyph->x_advance = x_advance;
sub_font_glyph->y_advance = y_advance;
+ sub_font_glyph->is_latin = (latin_character >= 0);
+ sub_font_glyph->latin_character = latin_character;
sub_font_glyph->is_mapped = FALSE;
- sub_font_glyph->unicode = -1;
- sub_font_glyph->utf8 = NULL;
- sub_font_glyph->utf8_len = 0;
+ sub_font_glyph->unicode = unicode;
+ sub_font_glyph->utf8 = utf8;
+ sub_font_glyph->utf8_len = utf8_len;
return sub_font_glyph;
}
@@ -266,8 +276,6 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
cairo_sub_font_t **sub_font_out)
{
cairo_sub_font_t *sub_font;
- cairo_status_t status;
- cairo_scaled_font_subsets_glyph_t subset_glyph;
sub_font = malloc (sizeof (cairo_sub_font_t));
if (unlikely (sub_font == NULL))
@@ -282,8 +290,13 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
sub_font->scaled_font = scaled_font;
sub_font->font_id = font_id;
- sub_font->current_subset = 0;
+ if (parent->use_latin_subset)
+ sub_font->current_subset = 1; /* reserve subset 0 for latin glyphs */
+ else
+ sub_font->current_subset = 0;
+
sub_font->num_glyphs_in_current_subset = 0;
+ sub_font->num_glyphs_in_latin_subset = 0;
sub_font->max_glyphs_per_subset = max_glyphs_per_subset;
sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal);
@@ -292,18 +305,6 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
sub_font->next = NULL;
-
- /* Reserve first glyph in subset for the .notdef glyph except for
- * Type 3 fonts */
- if (! is_scaled) {
- status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, -1, &subset_glyph);
- if (unlikely (status)) {
- _cairo_hash_table_destroy (sub_font->sub_font_glyphs);
- free (sub_font);
- return status;
- }
- }
-
*sub_font_out = sub_font;
return CAIRO_STATUS_SUCCESS;
}
@@ -329,10 +330,36 @@ _cairo_sub_font_pluck (void *entry, void *closure)
_cairo_sub_font_destroy (sub_font);
}
+/* Characters 0x80 to 0x9f in the winansi encoding.
+ * All other characters in the range 0x00 to 0xff map 1:1 to unicode */
+static unsigned int _winansi_0x80_to_0x9f[] = {
+ 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021,
+ 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000,
+ 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
+ 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178
+};
+
+static int _unicode_to_winansi (unsigned long unicode)
+{
+ int i;
+
+ if (unicode < 0x80 || (unicode >= 0xa0 && unicode <= 0xff))
+ return unicode;
+
+ for (i = 0; i < 32; i++) {
+ if (_winansi_0x80_to_0x9f[i] == unicode)
+ return i + 0x80;
+ }
+
+ return -1;
+}
+
static cairo_status_t
-_cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
- cairo_scaled_font_t *scaled_font,
- unsigned long scaled_font_glyph_index)
+_cairo_sub_font_glyph_lookup_unicode (cairo_scaled_font_t *scaled_font,
+ unsigned long scaled_font_glyph_index,
+ uint32_t *unicode_out,
+ char **utf8_out,
+ int *utf8_len_out)
{
uint32_t unicode;
char buf[8];
@@ -356,19 +383,19 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
return status;
}
- sub_font_glyph->unicode = unicode;
- sub_font_glyph->utf8 = NULL;
- sub_font_glyph->utf8_len = 0;
+ *unicode_out = unicode;
+ *utf8_out = NULL;
+ *utf8_len_out = 0;
if (unicode != (uint32_t) -1) {
len = _cairo_ucs4_to_utf8 (unicode, buf);
if (len > 0) {
- sub_font_glyph->utf8 = malloc (len + 1);
- if (unlikely (sub_font_glyph->utf8 == NULL))
+ *utf8_out = malloc (len + 1);
+ if (unlikely (*utf8_out == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- memcpy (sub_font_glyph->utf8, buf, len);
- sub_font_glyph->utf8[len] = 0;
- sub_font_glyph->utf8_len = len;
+ memcpy (*utf8_out, buf, len);
+ (*utf8_out)[len] = 0;
+ *utf8_len_out = len;
}
}
@@ -429,9 +456,14 @@ _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font,
if (sub_font_glyph != NULL) {
subset_glyph->font_id = sub_font->font_id;
subset_glyph->subset_id = sub_font_glyph->subset_id;
- subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index;
+ if (sub_font_glyph->is_latin)
+ subset_glyph->subset_glyph_index = sub_font_glyph->latin_character;
+ else
+ subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index;
+
subset_glyph->is_scaled = sub_font->is_scaled;
subset_glyph->is_composite = sub_font->is_composite;
+ subset_glyph->is_latin = sub_font_glyph->is_latin;
subset_glyph->x_advance = sub_font_glyph->x_advance;
subset_glyph->y_advance = sub_font_glyph->y_advance;
status = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph,
@@ -446,10 +478,109 @@ _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font,
}
static cairo_status_t
+_cairo_sub_font_add_glyph (cairo_sub_font_t *sub_font,
+ unsigned long scaled_font_glyph_index,
+ cairo_bool_t is_latin,
+ int latin_character,
+ uint32_t unicode,
+ char *utf8,
+ int utf8_len,
+ cairo_sub_font_glyph_t **sub_font_glyph_out)
+{
+ cairo_scaled_glyph_t *scaled_glyph;
+ cairo_sub_font_glyph_t *sub_font_glyph;
+ int *num_glyphs_in_subset_ptr;
+ double x_advance;
+ double y_advance;
+ cairo_status_t status;
+
+ _cairo_scaled_font_freeze_cache (sub_font->scaled_font);
+ status = _cairo_scaled_glyph_lookup (sub_font->scaled_font,
+ scaled_font_glyph_index,
+ CAIRO_SCALED_GLYPH_INFO_METRICS,
+ &scaled_glyph);
+ assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
+ if (unlikely (status)) {
+ _cairo_scaled_font_thaw_cache (sub_font->scaled_font);
+ return status;
+ }
+
+ x_advance = scaled_glyph->metrics.x_advance;
+ y_advance = scaled_glyph->metrics.y_advance;
+ _cairo_scaled_font_thaw_cache (sub_font->scaled_font);
+
+ if (unlikely (status)) {
+ _cairo_sub_font_glyph_destroy (sub_font_glyph);
+ return status;
+ }
+
+ if (!is_latin && sub_font->num_glyphs_in_current_subset == sub_font->max_glyphs_per_subset)
+ {
+ sub_font->current_subset++;
+ sub_font->num_glyphs_in_current_subset = 0;
+ }
+
+ if (is_latin)
+ num_glyphs_in_subset_ptr = &sub_font->num_glyphs_in_latin_subset;
+ else
+ num_glyphs_in_subset_ptr = &sub_font->num_glyphs_in_current_subset;
+
+ /* Reserve first glyph in subset for the .notdef glyph except for
+ * Type 3 fonts */
+ if (*num_glyphs_in_subset_ptr == 0 &&
+ scaled_font_glyph_index != 0 &&
+ ! _cairo_font_face_is_user (sub_font->scaled_font->font_face))
+ {
+ status = _cairo_sub_font_add_glyph (sub_font,
+ 0,
+ is_latin,
+ 0,
+ 0,
+ NULL,
+ -1,
+ &sub_font_glyph);
+ if (unlikely (status))
+ return status;
+ }
+
+ sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index,
+ is_latin ? 0 : sub_font->current_subset,
+ *num_glyphs_in_subset_ptr,
+ x_advance,
+ y_advance,
+ is_latin ? latin_character : -1,
+ unicode,
+ utf8,
+ utf8_len);
+
+ if (unlikely (sub_font_glyph == NULL))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
+ if (unlikely (status)) {
+ _cairo_sub_font_glyph_destroy (sub_font_glyph);
+ return status;
+ }
+
+ (*num_glyphs_in_subset_ptr)++;
+ if (sub_font->is_scaled) {
+ if (*num_glyphs_in_subset_ptr > sub_font->parent->max_glyphs_per_scaled_subset_used)
+ sub_font->parent->max_glyphs_per_scaled_subset_used = *num_glyphs_in_subset_ptr;
+ } else {
+ if (*num_glyphs_in_subset_ptr > sub_font->parent->max_glyphs_per_unscaled_subset_used)
+ sub_font->parent->max_glyphs_per_unscaled_subset_used = *num_glyphs_in_subset_ptr;
+ }
+
+ *sub_font_glyph_out = sub_font_glyph;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
_cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
unsigned long scaled_font_glyph_index,
- const char *utf8,
- int utf8_len,
+ const char *text_utf8,
+ int text_utf8_len,
cairo_scaled_font_subsets_glyph_t *subset_glyph)
{
cairo_sub_font_glyph_t key, *sub_font_glyph;
@@ -459,79 +590,64 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
sub_font_glyph = _cairo_hash_table_lookup (sub_font->sub_font_glyphs,
&key.base);
if (sub_font_glyph == NULL) {
- cairo_scaled_glyph_t *scaled_glyph;
+ uint32_t font_unicode;
+ char *font_utf8;
+ int font_utf8_len;
+ cairo_bool_t is_latin;
+ int latin_character;
+
+ status = _cairo_sub_font_glyph_lookup_unicode (sub_font->scaled_font,
+ scaled_font_glyph_index,
+ &font_unicode,
+ &font_utf8,
+ &font_utf8_len);
+ if (unlikely(status))
+ return status;
- if (sub_font->num_glyphs_in_current_subset == sub_font->max_glyphs_per_subset)
+ /* If glyph is in the winansi encoding and font is not a user
+ * font, put glyph in the latin subset. If glyph is .notdef
+ * the latin subset is preferred but only if the latin subset
+ * already contains at least one glyph. We don't want to
+ * create a separate subset just for the .notdef glyph.
+ */
+ is_latin = FALSE;
+ if (sub_font->parent->use_latin_subset &&
+ (! _cairo_font_face_is_user (sub_font->scaled_font->font_face)))
{
- cairo_scaled_font_subsets_glyph_t tmp_subset_glyph;
-
- sub_font->current_subset++;
- sub_font->num_glyphs_in_current_subset = 0;
-
- /* Reserve first glyph in subset for the .notdef glyph
- * except for Type 3 fonts */
- if (! _cairo_font_face_is_user (sub_font->scaled_font->font_face)) {
- status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, -1, &tmp_subset_glyph);
- if (unlikely (status))
- return status;
+ latin_character = _unicode_to_winansi (font_unicode);
+ if (latin_character > 0 ||
+ (latin_character == 0 && sub_font->num_glyphs_in_latin_subset > 0))
+ {
+ is_latin = TRUE;
}
}
- _cairo_scaled_font_freeze_cache (sub_font->scaled_font);
- status = _cairo_scaled_glyph_lookup (sub_font->scaled_font,
- scaled_font_glyph_index,
- CAIRO_SCALED_GLYPH_INFO_METRICS,
- &scaled_glyph);
- assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
- if (unlikely (status)) {
- _cairo_scaled_font_thaw_cache (sub_font->scaled_font);
- return status;
- }
-
- sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index,
- sub_font->current_subset,
- sub_font->num_glyphs_in_current_subset,
- scaled_glyph->metrics.x_advance,
- scaled_glyph->metrics.y_advance);
- _cairo_scaled_font_thaw_cache (sub_font->scaled_font);
-
- if (unlikely (sub_font_glyph == NULL))
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
- status = _cairo_sub_font_glyph_lookup_unicode (sub_font_glyph,
- sub_font->scaled_font,
- scaled_font_glyph_index);
- if (unlikely (status)) {
- _cairo_sub_font_glyph_destroy (sub_font_glyph);
- return status;
- }
-
- status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
- if (unlikely (status)) {
- _cairo_sub_font_glyph_destroy (sub_font_glyph);
+ status = _cairo_sub_font_add_glyph (sub_font,
+ scaled_font_glyph_index,
+ is_latin,
+ latin_character,
+ font_unicode,
+ font_utf8,
+ font_utf8_len,
+ &sub_font_glyph);
+ if (unlikely(status))
return status;
- }
-
- sub_font->num_glyphs_in_current_subset++;
-
- if (sub_font->is_scaled) {
- if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_scaled_subset_used)
- sub_font->parent->max_glyphs_per_scaled_subset_used = sub_font->num_glyphs_in_current_subset;
- } else {
- if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_unscaled_subset_used)
- sub_font->parent->max_glyphs_per_unscaled_subset_used = sub_font->num_glyphs_in_current_subset;
- }
}
subset_glyph->font_id = sub_font->font_id;
subset_glyph->subset_id = sub_font_glyph->subset_id;
- subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index;
+ if (sub_font_glyph->is_latin)
+ subset_glyph->subset_glyph_index = sub_font_glyph->latin_character;
+ else
+ subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index;
+
subset_glyph->is_scaled = sub_font->is_scaled;
subset_glyph->is_composite = sub_font->is_composite;
+ subset_glyph->is_latin = sub_font_glyph->is_latin;
subset_glyph->x_advance = sub_font_glyph->x_advance;
subset_glyph->y_advance = sub_font_glyph->y_advance;
status = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph,
- utf8, utf8_len,
+ text_utf8, text_utf8_len,
&subset_glyph->utf8_is_mapped);
subset_glyph->unicode = sub_font_glyph->unicode;
@@ -616,6 +732,7 @@ _cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type)
}
subsets->type = type;
+ subsets->use_latin_subset = FALSE;
subsets->max_glyphs_per_unscaled_subset_used = 0;
subsets->max_glyphs_per_scaled_subset_used = 0;
subsets->num_sub_fonts = 0;
@@ -670,6 +787,13 @@ _cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *subsets)
free (subsets);
}
+void
+_cairo_scaled_font_subsets_enable_latin_subset (cairo_scaled_font_subsets_t *font_subsets,
+ cairo_bool_t use_latin)
+{
+ font_subsets->use_latin_subset = use_latin;
+}
+
cairo_status_t
_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
cairo_scaled_font_t *scaled_font,
commit 3f817dcfd39ffdb73ac694fd90a47d9d3a42af74
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 1 17:41:28 2010 +0930
Fix font metrics in PDF Type 1 fonts
edcefa87 introduced a bug in the Type 1 font metrics in PDF files.
diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index d92c860..9c0a2cf 100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -1356,12 +1356,12 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
font.glyphs[i].width;
}
- type1_subset->x_min = font.base.x_min;
- type1_subset->y_min = font.base.y_min;
- type1_subset->x_max = font.base.x_max;
- type1_subset->y_max = font.base.y_max;
- type1_subset->ascent = font.base.ascent;
- type1_subset->descent = font.base.descent;
+ type1_subset->x_min = font.base.x_min/1000.0;
+ type1_subset->y_min = font.base.y_min/1000.0;
+ type1_subset->x_max = font.base.x_max/1000.0;
+ type1_subset->y_max = font.base.y_max/1000.0;
+ type1_subset->ascent = font.base.ascent/1000.0;
+ type1_subset->descent = font.base.descent/1000.0;
length = font.base.header_size +
font.base.data_size +
More information about the cairo-commit
mailing list