From c3663324fd417a281e9cd872aa1d60101ff4602b Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Thu, 11 Sep 2008 08:38:39 +0930 Subject: [PATCH] Add _cairo_type3_glyph_surface_analyze_glyph() This function emits the glyph to a null stream with the side effect that other glyphs referenced by this user-font glyph will be added to the font subsets. --- src/cairo-pdf-surface.c | 28 ++++++++++++++++++ src/cairo-ps-surface.c | 30 +++++++++++++++++++ src/cairo-type3-glyph-surface-private.h | 4 +++ src/cairo-type3-glyph-surface.c | 39 +++++++++++++++++++++++++ 4 files changed, 101 insertions(+) diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index ab51871af..b783b53c1 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -3480,6 +3480,28 @@ _cairo_pdf_emit_imagemask (cairo_image_surface_t *image, return _cairo_output_stream_get_status (stream); } +static cairo_status_t +_cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset, + void *closure) +{ + cairo_status_t status = CAIRO_STATUS_SUCCESS; + unsigned int i; + cairo_surface_t *type3_surface; + + type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font, + NULL, + _cairo_pdf_emit_imagemask); + for (i = 1; i < font_subset->num_glyphs; i++) { + status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface, + font_subset->glyphs[i]); + if (status) + break; + } + cairo_surface_destroy (type3_surface); + + return status; +} + static cairo_status_t _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, cairo_scaled_font_subset_t *font_subset) @@ -3713,6 +3735,12 @@ _cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface) { cairo_status_t status; + status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets, + _cairo_pdf_surface_analyze_user_font_subset, + surface); + if (status) + goto BAIL; + status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets, _cairo_pdf_surface_emit_unscaled_font_subset, surface); diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 24b160246..ba6e3f8a0 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -441,6 +441,30 @@ _cairo_ps_emit_imagemask (cairo_image_surface_t *image, return _cairo_output_stream_get_status (stream); } +static cairo_status_t +_cairo_ps_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset, + void *closure) +{ + cairo_status_t status = CAIRO_STATUS_SUCCESS; + unsigned int i; + cairo_surface_t *type3_surface; + + type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font, + NULL, + _cairo_ps_emit_imagemask); + + for (i = 1; i < font_subset->num_glyphs; i++) { + status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface, + font_subset->glyphs[i]); + if (status) + break; + + } + cairo_surface_destroy (type3_surface); + + return status; +} + static cairo_status_t _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface, cairo_scaled_font_subset_t *font_subset) @@ -601,6 +625,12 @@ _cairo_ps_surface_emit_font_subsets (cairo_ps_surface_t *surface) "%% _cairo_ps_surface_emit_font_subsets\n"); #endif + status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets, + _cairo_ps_surface_analyze_user_font_subset, + surface); + if (status) + goto BAIL; + status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets, _cairo_ps_surface_emit_unscaled_font_subset, surface); diff --git a/src/cairo-type3-glyph-surface-private.h b/src/cairo-type3-glyph-surface-private.h index 47aba01c8..18538970a 100644 --- a/src/cairo-type3-glyph-surface-private.h +++ b/src/cairo-type3-glyph-surface-private.h @@ -62,6 +62,10 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font, cairo_output_stream_t *stream, cairo_type3_glyph_surface_emit_image_t emit_image); +cairo_private cairo_status_t +_cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface, + unsigned long glyph_index); + cairo_private cairo_status_t _cairo_type3_glyph_surface_emit_notdef_glyph (void *abstract_surface, cairo_output_stream_t *stream, diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c index 4c3afb40a..aa2fda823 100644 --- a/src/cairo-type3-glyph-surface.c +++ b/src/cairo-type3-glyph-surface.c @@ -41,6 +41,7 @@ #include "cairo-type3-glyph-surface-private.h" #include "cairo-output-stream-private.h" #include "cairo-meta-surface-private.h" +#include "cairo-analysis-surface-private.h" static const cairo_surface_backend_t cairo_type3_glyph_surface_backend; @@ -348,6 +349,44 @@ _cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *sur return _cairo_type3_glyph_surface_emit_image (surface, image, &mat); } +cairo_status_t +_cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface, + unsigned long glyph_index) +{ + cairo_type3_glyph_surface_t *surface = abstract_surface; + cairo_scaled_glyph_t *scaled_glyph; + cairo_status_t status, status2; + cairo_output_stream_t *null_stream; + + null_stream = _cairo_null_stream_create (); + _cairo_type3_glyph_surface_set_stream (surface, null_stream); + status = _cairo_scaled_glyph_lookup (surface->scaled_font, + glyph_index, + CAIRO_SCALED_GLYPH_INFO_METRICS | + CAIRO_SCALED_GLYPH_INFO_META_SURFACE, + &scaled_glyph); + if (status && status != CAIRO_INT_STATUS_UNSUPPORTED) + goto cleanup; + + if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + status = CAIRO_STATUS_SUCCESS; + goto cleanup; + } + + status = _cairo_meta_surface_replay (scaled_glyph->meta_surface, + &surface->base); + + if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) + status = CAIRO_STATUS_SUCCESS; + +cleanup: + status2 = _cairo_output_stream_destroy (null_stream); + if (status) + return status; + + return status2; +} + cairo_status_t _cairo_type3_glyph_surface_emit_notdef_glyph (void *abstract_surface, cairo_output_stream_t *stream,