From f4f11eba5b6daa6f82b967dcb21715b7f16d9719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 16 May 2006 19:01:15 -0400 Subject: [PATCH] Output pdf dicts for truetype subset fonts. --- src/cairo-font-subset.c | 21 ++++++ src/cairo-pdf-surface.c | 97 ++++++++++++++++++++++++- src/cairo-scaled-font-subsets-private.h | 41 +++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) diff --git a/src/cairo-font-subset.c b/src/cairo-font-subset.c index c504f2e0a..5a1fcd170 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" @@ -755,3 +756,23 @@ static cairo_font_subset_backend_t cairo_pdf_ft_font_backend = { cairo_pdf_ft_font_generate, cairo_pdf_ft_font_destroy }; + +cairo_private cairo_status_t +_cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset, + cairo_scaled_font_subset_t *font_subset) +{ + cairo_unscaled_font_t *unscaled; + + unscaled = _cairo_ft_scaled_font_get_unscaled_font (font_subset->scaled_font); + + return CAIRO_INT_STATUS_UNSUPPORTED; +} + +cairo_private 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 8cde5e4d1..30ae914ec 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1667,7 +1667,102 @@ static cairo_status_t _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, cairo_scaled_font_subset_t *font_subset) { - return CAIRO_INT_STATUS_UNSUPPORTED; + 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 void diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h index aed01a306..a0b0dbcc7 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 */