diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c index a4a434f77..48cab1462 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 c60e6360f..32653122d 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 7c5756f49..44b037a41 100644 --- a/src/cairo-scaled-font-subsets-private.h +++ b/src/cairo-scaled-font-subsets-private.h @@ -386,6 +386,15 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset, 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 diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c index 677bd5ae4..79a778ff1 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 {