diff --git a/src/Makefile.am b/src/Makefile.am index 296822802..59d153189 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,14 +1,19 @@ +font_subset_sources = \ + cairo-font-subset.c \ + cairo-font-subset-private.h \ + cairo-scaled-font-subsets.c \ + cairo-scaled-font-subsets-private.h if CAIRO_HAS_PS_SURFACE libcairo_ps_headers = cairo-ps.h -libcairo_ps_sources = cairo-ps-surface.c cairo-ps-test.h cairo-scaled-font-subsets.c cairo-scaled-font-subsets-private.h -libcairo_font_subset_sources = cairo-font-subset.c cairo-font-subset-private.h +libcairo_ps_sources = cairo-ps-surface.c cairo-ps-test.h +libcairo_font_subset_sources = $(font_subset_sources) endif if CAIRO_HAS_PDF_SURFACE libcairo_pdf_headers = cairo-pdf.h libcairo_pdf_sources = cairo-pdf-surface.c cairo-pdf-test.h -libcairo_font_subset_sources = cairo-font-subset.c cairo-font-subset-private.h +libcairo_font_subset_sources = $(font_subset_sources) endif if CAIRO_HAS_PNG_FUNCTIONS @@ -18,6 +23,7 @@ endif if CAIRO_HAS_SVG_SURFACE libcairo_svg_headers = cairo-svg.h libcairo_svg_sources = cairo-svg-surface.c cairo-svg-test.h +libcairo_font_subset_sources = $(font_subset_sources) endif if CAIRO_HAS_TEST_SURFACES diff --git a/src/cairo-font-subset.c b/src/cairo-font-subset.c index ab7dc8197..2bc8ed2fe 100644 --- a/src/cairo-font-subset.c +++ b/src/cairo-font-subset.c @@ -35,6 +35,7 @@ #include "cairoint.h" #include "cairo-font-subset-private.h" +#include "cairo-scaled-font-subsets-private.h" /* XXX: Eventually, we need to handle other font backends */ #include "cairo-ft-private.h" @@ -51,28 +52,31 @@ struct ft_subset_glyph { unsigned long location; }; -struct cairo_font_subset_backend { - int (*use_glyph) (void *abstract_font, - int glyph); - cairo_status_t (*generate) (void *abstract_font, - const char **data, - unsigned long *length); - void (*destroy) (void *abstract_font); -}; +typedef struct _cairo_ft_font { + + cairo_scaled_font_subset_t *scaled_font_subset; + + struct { + cairo_unscaled_font_t *unscaled_font; + unsigned int font_id; + char *base_font; + int num_glyphs; + int *widths; + long x_min, y_min, x_max, y_max; + long ascent, descent; + } base; -typedef struct cairo_pdf_ft_font cairo_pdf_ft_font_t; -struct cairo_pdf_ft_font { - cairo_font_subset_t base; ft_subset_glyph_t *glyphs; FT_Face face; int checksum_index; cairo_array_t output; int *parent_to_subset; cairo_status_t status; -}; + +} cairo_pdf_ft_font_t; static int -cairo_pdf_ft_font_use_glyph (void *abstract_font, int glyph); +cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph); #define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) ) @@ -113,56 +117,44 @@ be32_to_cpu(unsigned long v) #endif -static cairo_font_subset_backend_t cairo_pdf_ft_font_backend; - -int -_cairo_font_subset_use_glyph (cairo_font_subset_t *font, int glyph) -{ - return font->backend->use_glyph (font, glyph); -} - -cairo_status_t -_cairo_font_subset_generate (cairo_font_subset_t *font, - const char **data, unsigned long *length) -{ - return font->backend->generate (font, data, length); -} - -void -_cairo_font_subset_destroy (cairo_font_subset_t *font) -{ - font->backend->destroy (font); -} - -cairo_font_subset_t * -_cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font) +static cairo_status_t +_cairo_pdf_ft_font_create (cairo_scaled_font_subset_t *scaled_font_subset, + cairo_pdf_ft_font_t **font_return) { + cairo_unscaled_font_t *unscaled_font; cairo_ft_unscaled_font_t *ft_unscaled_font; - FT_Face face; + cairo_status_t status = CAIRO_STATUS_NO_MEMORY; cairo_pdf_ft_font_t *font; + FT_Face face; unsigned long size; int i, j; /* XXX: Need to fix this to work with a general cairo_unscaled_font_t. */ - if (! _cairo_unscaled_font_is_ft (unscaled_font)) - return NULL; + if (!_cairo_scaled_font_is_ft (scaled_font_subset->scaled_font)) + return CAIRO_INT_STATUS_UNSUPPORTED; + + unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font_subset->scaled_font); ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font; face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font); + if (face == NULL) + /* Assume out of memory */ + return CAIRO_STATUS_NO_MEMORY; /* We currently only support freetype truetype fonts. */ size = 0; if (!FT_IS_SFNT (face) || FT_Load_Sfnt_Table (face, TTAG_glyf, 0, NULL, &size) != 0) - return NULL; + return CAIRO_INT_STATUS_UNSUPPORTED; font = malloc (sizeof (cairo_pdf_ft_font_t)); if (font == NULL) - return NULL; + return CAIRO_STATUS_NO_MEMORY; + + font->scaled_font_subset = scaled_font_subset; font->base.unscaled_font = _cairo_unscaled_font_reference (unscaled_font); - font->base.backend = &cairo_pdf_ft_font_backend; _cairo_array_init (&font->output, sizeof (char)); if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS) @@ -176,7 +168,7 @@ _cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font) if (font->parent_to_subset == NULL) goto fail3; - font->base.num_glyphs = 1; + font->base.num_glyphs = 0; font->base.x_min = face->bbox.xMin; font->base.y_min = face->bbox.yMin; font->base.x_max = face->bbox.xMax; @@ -202,7 +194,9 @@ _cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font) font->status = CAIRO_STATUS_SUCCESS; - return &font->base; + *font_return = font; + + return CAIRO_STATUS_SUCCESS; fail5: free (font->base.base_font); @@ -214,14 +208,13 @@ _cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font) _cairo_array_fini (&font->output); fail1: free (font); - return NULL; + + return status; } static void -cairo_pdf_ft_font_destroy (void *abstract_font) +cairo_pdf_ft_font_destroy (cairo_pdf_ft_font_t *font) { - cairo_pdf_ft_font_t *font = abstract_font; - _cairo_unscaled_font_destroy (font->base.unscaled_font); free (font->base.base_font); free (font->parent_to_subset); @@ -735,10 +728,8 @@ cairo_pdf_ft_font_generate (void *abstract_font, } static int -cairo_pdf_ft_font_use_glyph (void *abstract_font, int glyph) +cairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph) { - cairo_pdf_ft_font_t *font = abstract_font; - if (font->parent_to_subset[glyph] == 0) { font->parent_to_subset[glyph] = font->base.num_glyphs; font->glyphs[font->base.num_glyphs].parent_index = glyph; @@ -748,8 +739,72 @@ cairo_pdf_ft_font_use_glyph (void *abstract_font, int glyph) return font->parent_to_subset[glyph]; } -static cairo_font_subset_backend_t cairo_pdf_ft_font_backend = { - cairo_pdf_ft_font_use_glyph, - cairo_pdf_ft_font_generate, - cairo_pdf_ft_font_destroy -}; +cairo_status_t +_cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset, + cairo_scaled_font_subset_t *font_subset) +{ + cairo_pdf_ft_font_t *font; + cairo_status_t status; + const char *data; + unsigned long length, parent_glyph; + int i; + + status = _cairo_pdf_ft_font_create (font_subset, &font); + if (status) + return status; + + for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { + parent_glyph = font->scaled_font_subset->glyphs[i]; + cairo_pdf_ft_font_use_glyph (font, parent_glyph); + } + + status = cairo_pdf_ft_font_generate (font, &data, &length); + if (status) + goto fail1; + + truetype_subset->base_font = strdup (font->base.base_font); + if (truetype_subset->base_font == NULL) + goto fail1; + + truetype_subset->widths = calloc (sizeof (int), font->base.num_glyphs); + if (truetype_subset->widths == NULL) + goto fail2; + for (i = 0; i < font->base.num_glyphs; i++) + truetype_subset->widths[i] = font->base.widths[i]; + + truetype_subset->x_min = font->base.x_min; + truetype_subset->y_min = font->base.y_min; + truetype_subset->x_max = font->base.x_max; + truetype_subset->y_max = font->base.y_max; + truetype_subset->ascent = font->base.ascent; + truetype_subset->descent = font->base.descent; + + truetype_subset->data = malloc (length); + if (truetype_subset->data == NULL) + goto fail3; + + memcpy (truetype_subset->data, data, length); + truetype_subset->data_length = length; + + cairo_pdf_ft_font_destroy (font); + + return CAIRO_STATUS_SUCCESS; + + fail3: + free (truetype_subset->widths); + fail2: + free (truetype_subset->base_font); + fail1: + cairo_pdf_ft_font_destroy (font); + + return status; +} + +void +_cairo_truetype_subset_fini (cairo_truetype_subset_t *subset) +{ + free (subset->base_font); + free (subset->widths); + free (subset->data); +} + diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index e365b77ac..a5e5bebbd 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1579,6 +1579,108 @@ _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface) "endobj\r\n"); } +static cairo_status_t +_cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, + cairo_scaled_font_subset_t *font_subset) +{ + cairo_pdf_resource_t stream, descriptor, subset_resource; + cairo_status_t status; + cairo_pdf_font_t font; + cairo_truetype_subset_t subset; + unsigned long compressed_length; + char *compressed; + int i; + + status = _cairo_truetype_subset_init (&subset, font_subset); + if (status) + return status; + + compressed = compress_dup (subset.data, subset.data_length, + &compressed_length); + if (compressed == NULL) { + _cairo_truetype_subset_fini (&subset); + return CAIRO_STATUS_NO_MEMORY; + } + + stream = _cairo_pdf_surface_new_object (surface); + _cairo_output_stream_printf (surface->output, + "%d 0 obj\r\n" + "<< /Filter /FlateDecode\r\n" + " /Length %lu\r\n" + " /Length1 %lu\r\n" + ">>\r\n" + "stream\r\n", + stream.id, + compressed_length, + subset.data_length); + _cairo_output_stream_write (surface->output, compressed, compressed_length); + _cairo_output_stream_printf (surface->output, + "\r\n" + "endstream\r\n" + "endobj\r\n"); + free (compressed); + + descriptor = _cairo_pdf_surface_new_object (surface); + _cairo_output_stream_printf (surface->output, + "%d 0 obj\r\n" + "<< /Type /FontDescriptor\r\n" + " /FontName /7%s\r\n" + " /Flags 4\r\n" + " /FontBBox [ %ld %ld %ld %ld ]\r\n" + " /ItalicAngle 0\r\n" + " /Ascent %ld\r\n" + " /Descent %ld\r\n" + " /CapHeight 500\r\n" + " /StemV 80\r\n" + " /StemH 80\r\n" + " /FontFile2 %u 0 R\r\n" + ">>\r\n" + "endobj\r\n", + descriptor.id, + subset.base_font, + subset.x_min, + subset.y_min, + subset.x_max, + subset.y_max, + subset.ascent, + subset.descent, + stream.id); + + subset_resource = _cairo_pdf_surface_new_object (surface); + _cairo_output_stream_printf (surface->output, + "%d 0 obj\r\n" + "<< /Type /Font\r\n" + " /Subtype /TrueType\r\n" + " /BaseFont /%s\r\n" + " /FirstChar 0\r\n" + " /LastChar %d\r\n" + " /FontDescriptor %d 0 R\r\n" + " /Widths [", + subset_resource.id, + subset.base_font, + font_subset->num_glyphs, + descriptor.id); + + for (i = 0; i < font_subset->num_glyphs; i++) + _cairo_output_stream_printf (surface->output, + " %d", + subset.widths[i]); + + _cairo_output_stream_printf (surface->output, + " ]\r\n" + ">>\r\n" + "endobj\r\n"); + + font.font_id = font_subset->font_id; + font.subset_id = font_subset->subset_id; + font.subset_resource = subset_resource; + _cairo_array_append (&surface->fonts, &font); + + _cairo_truetype_subset_fini (&subset); + + return CAIRO_STATUS_SUCCESS; +} + static cairo_int_status_t _cairo_pdf_surface_emit_outline_glyph_data (cairo_pdf_surface_t *surface, cairo_scaled_font_t *scaled_font, @@ -1678,19 +1780,19 @@ _cairo_pdf_surface_emit_glyph (cairo_pdf_surface_t *surface, _cairo_surface_set_error (&surface->base, status); } -static void -_cairo_pdf_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset, - void *closure) +static cairo_status_t +_cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, + cairo_scaled_font_subset_t *font_subset) { - cairo_pdf_surface_t *surface = closure; cairo_pdf_resource_t *glyphs, encoding, char_procs, subset_resource; cairo_pdf_font_t font; + cairo_matrix_t matrix; int i; glyphs = malloc (font_subset->num_glyphs * sizeof (cairo_pdf_resource_t)); if (glyphs == NULL) { _cairo_surface_set_error (&surface->base, CAIRO_STATUS_NO_MEMORY); - return; + return CAIRO_STATUS_NO_MEMORY; } for (i = 0; i < font_subset->num_glyphs; i++) { @@ -1726,17 +1828,23 @@ _cairo_pdf_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset, "endobj\r\n"); subset_resource = _cairo_pdf_surface_new_object (surface); + matrix = font_subset->scaled_font->scale; + cairo_matrix_invert (&matrix); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Type /Font\r\n" " /Subtype /Type3\r\n" " /FontBBox [0 0 0 0]\r\n" - " /FontMatrix\t[1 0 0 1 0 0]\r\n" + " /FontMatrix [ %f %f %f %f 0 0 ]\r\n" " /Encoding %d 0 R\r\n" " /CharProcs %d 0 R\r\n" " /FirstChar 0\r\n" " /LastChar %d\r\n", subset_resource.id, + matrix.xx, + matrix.yx, + -matrix.xy, + -matrix.yy, encoding.id, char_procs.id, font_subset->num_glyphs - 1); @@ -1756,6 +1864,24 @@ _cairo_pdf_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset, font.subset_id = font_subset->subset_id; font.subset_resource = subset_resource; _cairo_array_append (&surface->fonts, &font); + + return CAIRO_STATUS_SUCCESS; +} + +static void +_cairo_pdf_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset, + void *closure) +{ + cairo_pdf_surface_t *surface = closure; + cairo_status_t status; + + status = _cairo_pdf_surface_emit_truetype_font_subset (surface, font_subset); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return; + + status = _cairo_pdf_surface_emit_type3_font_subset (surface, font_subset); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return; } static cairo_status_t @@ -2330,6 +2456,9 @@ _cairo_pdf_surface_show_glyphs (void *abstract_surface, if (status) return status; + _cairo_output_stream_printf (surface->output, + "BT\r\n"); + for (i = 0; i < num_glyphs; i++) { status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets, scaled_font, glyphs[i].index, @@ -2343,13 +2472,22 @@ _cairo_pdf_surface_show_glyphs (void *abstract_surface, font_id, subset_id); current_subset_id = subset_id; } + _cairo_output_stream_printf (surface->output, - "BT %f %f Td <%c%c> Tj ET\r\n", - glyphs[i].x, glyphs[i].y, + "%f %f %f %f %f %f Tm <%c%c> Tj\r\n", + scaled_font->scale.xx, + scaled_font->scale.yx, + -scaled_font->scale.xy, + -scaled_font->scale.yy, + glyphs[i].x, + glyphs[i].y, hex_digit (subset_glyph_index >> 4), hex_digit (subset_glyph_index)); } + _cairo_output_stream_printf (surface->output, + "ET\r\n"); + return _cairo_output_stream_get_status (surface->output); } diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 6553bce36..ed6bcca5b 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -209,6 +209,73 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface) } } +static cairo_status_t +_cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface, + cairo_scaled_font_subset_t *font_subset) + + +{ + cairo_truetype_subset_t subset; + cairo_status_t status; + int i; + + status = _cairo_truetype_subset_init (&subset, font_subset); + if (status) + return status; + + /* FIXME: Figure out document structure convention for fonts */ + + _cairo_output_stream_printf (surface->final_stream, + "%% _cairo_ps_surface_emit_truetype_font_subset\n"); + + _cairo_output_stream_printf (surface->final_stream, + "11 dict begin\n" + "/FontType 42 def\n" + "/FontName /CairoFont-%d-%d def\n" + "/PaintType 0 def\n" + "/FontMatrix [ 1 0 0 1 0 0 ] def\n" + "/FontBBox [ 0 0 0 0 ] def\n" + "/Encoding 256 array def\n" + "0 1 255 { Encoding exch /.notdef put } for\n", + font_subset->font_id, + font_subset->subset_id); + + /* FIXME: Figure out how subset->x_max etc maps to the /FontBBox */ + + for (i = 1; i < font_subset->num_glyphs; i++) + _cairo_output_stream_printf (surface->final_stream, + "Encoding %d /g%d put\n", i, i); + + _cairo_output_stream_printf (surface->final_stream, + "/CharStrings %d dict dup begin\n" + "/.notdef 0 def\n", + font_subset->num_glyphs); + + for (i = 1; i < font_subset->num_glyphs; i++) + _cairo_output_stream_printf (surface->final_stream, + "/g%d %d def\n", i, i); + + _cairo_output_stream_printf (surface->final_stream, + "end readonly def\n"); + + /* FIXME: We need to break up fonts bigger than 64k so we don't + * exceed string size limitation. At glyph boundaries. Stupid + * postscript. */ + _cairo_output_stream_printf (surface->final_stream, + "/sfnts [<"); + + _cairo_output_stream_write_hex_string (surface->final_stream, + subset.data, subset.data_length); + + _cairo_output_stream_printf (surface->final_stream, + ">] def\n" + "FontName currentdict end definefont pop\n"); + + _cairo_truetype_subset_fini (&subset); + + return CAIRO_STATUS_SUCCESS; +} + static cairo_int_status_t _cairo_ps_surface_emit_outline_glyph_data (cairo_ps_surface_t *surface, cairo_scaled_font_t *scaled_font, @@ -304,27 +371,35 @@ _cairo_ps_surface_emit_glyph (cairo_ps_surface_t *surface, _cairo_surface_set_error (&surface->base, status); } -static void -_cairo_ps_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset, - void *closure) +static cairo_status_t +_cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface, + cairo_scaled_font_subset_t *font_subset) + + { - cairo_ps_surface_t *surface = closure; + cairo_matrix_t matrix; int i; _cairo_output_stream_printf (surface->final_stream, - "%% _cairo_ps_surface_emit_font_subset\n"); + "%% _cairo_ps_surface_emit_type3_font_subset\n"); _cairo_output_stream_printf (surface->final_stream, "/CairoFont-%d-%d <<\n", font_subset->font_id, font_subset->subset_id); + matrix = font_subset->scaled_font->scale; + cairo_matrix_invert (&matrix); _cairo_output_stream_printf (surface->final_stream, "\t/FontType\t3\n" - "\t/FontMatrix\t[1 0 0 1 0 0]\n" + "\t/FontMatrix\t[%f %f %f %f 0 0]\n" "\t/Encoding\t[0]\n" "\t/FontBBox\t[0 0 10 10]\n" - "\t/Glyphs [\n"); + "\t/Glyphs [\n", + matrix.xx, + matrix.yx, + -matrix.xy, + -matrix.yy); for (i = 0; i < font_subset->num_glyphs; i++) { _cairo_ps_surface_emit_glyph (surface, @@ -339,6 +414,25 @@ _cairo_ps_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset, "\t\texch get exec\n" "\t}\n" ">> definefont pop\n"); + + return CAIRO_STATUS_SUCCESS; +} + + +static void +_cairo_ps_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset, + void *closure) +{ + cairo_ps_surface_t *surface = closure; + cairo_status_t status; + + status = _cairo_ps_surface_emit_truetype_font_subset (surface, font_subset); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return; + + status = _cairo_ps_surface_emit_type3_font_subset (surface, font_subset); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return; } static cairo_status_t @@ -1785,10 +1879,18 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface, if (subset_id != current_subset_id) { _cairo_output_stream_printf (surface->stream, - "/CairoFont-%d-%d 1 selectfont\n", - font_id, subset_id); + "/CairoFont-%d-%d findfont\n" + "[ %f %f %f %f 0 0 ] makefont\n" + "setfont\n", + font_id, + subset_id, + scaled_font->scale.xx, + scaled_font->scale.yx, + -scaled_font->scale.xy, + -scaled_font->scale.yy); current_subset_id = subset_id; } + _cairo_output_stream_printf (surface->stream, "%f %f M <%c%c> S\n", glyphs[i].x, glyphs[i].y, diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h index f8b5ac897..b6499891d 100644 --- a/src/cairo-scaled-font-subsets-private.h +++ b/src/cairo-scaled-font-subsets-private.h @@ -179,4 +179,45 @@ _cairo_scaled_font_subsets_foreach (cairo_scaled_font_subsets_t *font_subsets, cairo_scaled_font_subset_callback_func_t font_subset_callback, void *closure); + +typedef struct _cairo_truetype_subset { + char *base_font; + int *widths; + long x_min, y_min, x_max, y_max; + long ascent, descent; + char *data; + unsigned long data_length; +} cairo_truetype_subset_t; + +/** + * _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. + * + * 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 (cairo_truetype_subset_t *truetype_subset, + cairo_scaled_font_subset_t *font_subset); + +/** + * _cairo_truetype_subset_fini: + * @truetype_subset: a #cairo_truetype_subset_t + * + * Free all resources associated with @truetype_subset. After this + * call, @truetype_subset should not be used again without a + * subsequent call to _cairo_truetype_subset_init() again first. + **/ +cairo_private void +_cairo_truetype_subset_fini (cairo_truetype_subset_t *truetype_subset); + #endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */