[cairo-commit] 5 commits - src/cairo-output-stream.c src/cairo-output-stream-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-type3-glyph-surface.c src/cairo-type3-glyph-surface-private.h

Adrian Johnson ajohnson at kemper.freedesktop.org
Wed Sep 10 16:31:13 PDT 2008


 src/cairo-output-stream-private.h       |    4 +
 src/cairo-output-stream.c               |   23 ++++++++
 src/cairo-pdf-surface.c                 |   54 ++++++++++++++++++
 src/cairo-ps-surface.c                  |   43 ++++++++++++++
 src/cairo-scaled-font-subsets-private.h |   35 ++++++++++++
 src/cairo-scaled-font-subsets.c         |   23 +++++++-
 src/cairo-type3-glyph-surface-private.h |   12 +++-
 src/cairo-type3-glyph-surface.c         |   92 ++++++++++++++++++++++++++++++--
 8 files changed, 275 insertions(+), 11 deletions(-)

New commits:
commit d878924cf8ec2aea9a4f1bd27ac3a83566c0af5f
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Thu Sep 11 08:46:55 2008 +0930

    PS: execute type3 glyphs in their own dictionary
    
    The PS emulation of the PDF text operators stores some data on the
    user dict between calls to operators. When using the PDF text
    operators in type 3 glyphs, the PDF operators were overwriting the
    same data as the PDF operators in the page. Fix this by creating a new
    dictionary to execute each type 3 glyph in.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 3831f80..6bf16df 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -554,7 +554,8 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t		*surface,
 				 "/FontBBox [%f %f %f %f] def\n"
 				 "/BuildChar {\n"
 				 "  exch /Glyphs get\n"
-				 "  exch get exec\n"
+				 "  exch get\n"
+				 "  10 dict begin exec end\n"
 				 "} bind def\n"
 				 "currentdict\n"
 				 "end\n"
commit b56075ee51aaf570f85c1d59513e5e5116ae2b06
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Thu Sep 11 08:41:39 2008 +0930

    Enable show_glyphs inside of in user-font glyphs

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index b783b53..96e4479 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -3484,13 +3484,21 @@ static cairo_status_t
 _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset,
 					     void		        *closure)
 {
+    cairo_pdf_surface_t *surface = closure;
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     unsigned int i;
     cairo_surface_t *type3_surface;
+    cairo_output_stream_t *null_stream;
 
+    null_stream = _cairo_null_stream_create ();
     type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
-						       NULL,
-						       _cairo_pdf_emit_imagemask);
+						       null_stream,
+						       _cairo_pdf_emit_imagemask,
+						       surface->font_subsets);
+    _cairo_type3_glyph_surface_set_font_subsets_callback (type3_surface,
+							  _cairo_pdf_surface_add_font,
+							  surface);
+
     for (i = 1; i < font_subset->num_glyphs; i++) {
 	status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface,
 							   font_subset->glyphs[i]);
@@ -3498,6 +3506,7 @@ _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_su
 	    break;
     }
     cairo_surface_destroy (type3_surface);
+    status = _cairo_output_stream_destroy (null_stream);
 
     return status;
 }
@@ -3534,9 +3543,14 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t		*surface,
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
+    _cairo_pdf_group_resources_clear (&surface->resources);
     type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
 						       NULL,
-						       _cairo_pdf_emit_imagemask);
+						       _cairo_pdf_emit_imagemask,
+						       surface->font_subsets);
+    _cairo_type3_glyph_surface_set_font_subsets_callback (type3_surface,
+							  _cairo_pdf_surface_add_font,
+							  surface);
 
     for (i = 0; i < font_subset->num_glyphs; i++) {
 	status = _cairo_pdf_surface_open_stream (surface,
@@ -3664,6 +3678,10 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t		*surface,
 				 "]\n");
     free (widths);
 
+    _cairo_output_stream_printf (surface->output,
+				 "   /Resources\n");
+    _cairo_pdf_surface_emit_group_resources (surface, &surface->resources);
+
     if (to_unicode_stream.id != 0)
         _cairo_output_stream_printf (surface->output,
                                      "    /ToUnicode %d 0 R\n",
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index ba6e3f8..3831f80 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -445,13 +445,15 @@ static cairo_status_t
 _cairo_ps_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset,
 					    void		       *closure)
 {
+    cairo_ps_surface_t *surface = 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);
+						       _cairo_ps_emit_imagemask,
+						       surface->font_subsets);
 
     for (i = 1; i < font_subset->num_glyphs; i++) {
 	status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface,
@@ -492,7 +494,8 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t		*surface,
 
     type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
 						       NULL,
-						       _cairo_ps_emit_imagemask);
+						       _cairo_ps_emit_imagemask,
+						       surface->font_subsets);
 
     for (i = 1; i < font_subset->num_glyphs; i++) {
 	if (font_subset->glyph_names != NULL) {
diff --git a/src/cairo-type3-glyph-surface-private.h b/src/cairo-type3-glyph-surface-private.h
index 1853897..9dd6e85 100644
--- a/src/cairo-type3-glyph-surface-private.h
+++ b/src/cairo-type3-glyph-surface-private.h
@@ -60,7 +60,13 @@ typedef struct cairo_type3_glyph_surface {
 cairo_private cairo_surface_t *
 _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_type3_glyph_surface_emit_image_t emit_image,
+				   cairo_scaled_font_subsets_t 		 *font_subsets);
+
+cairo_private void
+_cairo_type3_glyph_surface_set_font_subsets_callback (void		     		    *abstract_surface,
+						      cairo_pdf_operators_use_font_subset_t  use_font_subset,
+						      void				    *closure);
 
 cairo_private cairo_status_t
 _cairo_type3_glyph_surface_analyze_glyph (void		     *abstract_surface,
diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c
index aa2fda8..a7476a3 100644
--- a/src/cairo-type3-glyph-surface.c
+++ b/src/cairo-type3-glyph-surface.c
@@ -48,7 +48,8 @@ static const cairo_surface_backend_t cairo_type3_glyph_surface_backend;
 cairo_surface_t *
 _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_type3_glyph_surface_emit_image_t emit_image,
+				   cairo_scaled_font_subsets_t 		 *font_subsets)
 {
     cairo_type3_glyph_surface_t *surface;
     cairo_matrix_t invert_y_axis;
@@ -75,7 +76,7 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t	 		 *scaled_font,
     _cairo_pdf_operators_init (&surface->pdf_operators,
 			       surface->stream,
 			       &surface->cairo_to_pdf,
-			       NULL);
+			       font_subsets);
 
     return &surface->base;
 }
@@ -264,10 +265,31 @@ _cairo_type3_glyph_surface_show_glyphs (void		     *abstract_surface,
 					cairo_scaled_font_t  *scaled_font,
 					int		     *remaining_glyphs)
 {
-    /* XXX: Some refactoring is required before we can add font
-     * subsets in the middle of emitting all the subsets. */
+    cairo_type3_glyph_surface_t *surface = abstract_surface;
+    cairo_int_status_t status;
+    cairo_scaled_font_t *font;
+    cairo_matrix_t ctm;
+    int i;
+
+    for (i = 0; i < num_glyphs; i++)
+	cairo_matrix_transform_point (&surface->cairo_to_pdf, &glyphs[i].x, &glyphs[i].y);
+
+    cairo_matrix_multiply (&ctm, &scaled_font->ctm, &scaled_font->scale_inverse);
+    font = cairo_scaled_font_create (scaled_font->font_face,
+				     &scaled_font->font_matrix,
+				     &ctm,
+				     &scaled_font->options);
+
+    status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators,
+						    NULL, 0,
+						    glyphs, num_glyphs,
+						    NULL, 0,
+						    FALSE,
+						    font);
 
-    return CAIRO_INT_STATUS_IMAGE_FALLBACK;
+    cairo_scaled_font_destroy (font);
+
+    return status;
 }
 
 static const cairo_surface_backend_t cairo_type3_glyph_surface_backend = {
@@ -349,6 +371,18 @@ _cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *sur
     return _cairo_type3_glyph_surface_emit_image (surface, image, &mat);
 }
 
+void
+_cairo_type3_glyph_surface_set_font_subsets_callback (void		     		    *abstract_surface,
+						      cairo_pdf_operators_use_font_subset_t  use_font_subset,
+						      void				    *closure)
+{
+    cairo_type3_glyph_surface_t *surface = abstract_surface;
+
+    _cairo_pdf_operators_set_font_subsets_callback (&surface->pdf_operators,
+						    use_font_subset,
+						    closure);
+}
+
 cairo_status_t
 _cairo_type3_glyph_surface_analyze_glyph (void		     *abstract_surface,
 					  unsigned long	      glyph_index)
@@ -376,6 +410,10 @@ _cairo_type3_glyph_surface_analyze_glyph (void		     *abstract_surface,
     status = _cairo_meta_surface_replay (scaled_glyph->meta_surface,
 					 &surface->base);
 
+    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+    if (status)
+	return status;
+
     if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK)
 	status = CAIRO_STATUS_SUCCESS;
 
@@ -469,6 +507,11 @@ _cairo_type3_glyph_surface_emit_glyph (void		     *abstract_surface,
 	_cairo_output_stream_printf (surface->stream, "q\n");
 	status = _cairo_meta_surface_replay (scaled_glyph->meta_surface,
 					 &surface->base);
+
+	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+	if (status)
+	    return status;
+
 	_cairo_output_stream_printf (surface->stream, "Q\n");
 
 	_cairo_type3_glyph_surface_set_stream (surface, stream);
commit c3663324fd417a281e9cd872aa1d60101ff4602b
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Thu Sep 11 08:38:39 2008 +0930

    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.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index ab51871..b783b53 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -3481,6 +3481,28 @@ _cairo_pdf_emit_imagemask (cairo_image_surface_t *image,
 }
 
 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 24b1602..ba6e3f8 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -442,6 +442,30 @@ _cairo_ps_emit_imagemask (cairo_image_surface_t *image,
 }
 
 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 47aba01..1853897 100644
--- a/src/cairo-type3-glyph-surface-private.h
+++ b/src/cairo-type3-glyph-surface-private.h
@@ -63,6 +63,10 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t	 		 *scaled_font,
 				   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,
 					      cairo_box_t           *bbox,
diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c
index 4c3afb4..aa2fda8 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;
 
@@ -349,6 +350,44 @@ _cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *sur
 }
 
 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,
 					      cairo_box_t           *bbox,
commit b74533b5a56c1d063f288343f2e8e484f3c6571f
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Thu Sep 11 08:37:30 2008 +0930

    Add null output stream

diff --git a/src/cairo-output-stream-private.h b/src/cairo-output-stream-private.h
index 37239f2..6c60f09 100644
--- a/src/cairo-output-stream-private.h
+++ b/src/cairo-output-stream-private.h
@@ -161,6 +161,9 @@ _cairo_memory_stream_copy (cairo_output_stream_t *base,
 cairo_private int
 _cairo_memory_stream_length (cairo_output_stream_t *stream);
 
+cairo_output_stream_t *
+_cairo_null_stream_create (void);
+
 /* cairo-base85-stream.c */
 cairo_private cairo_output_stream_t *
 _cairo_base85_stream_create (cairo_output_stream_t *output);
@@ -169,4 +172,5 @@ _cairo_base85_stream_create (cairo_output_stream_t *output);
 cairo_private cairo_output_stream_t *
 _cairo_deflate_stream_create (cairo_output_stream_t *output);
 
+
 #endif /* CAIRO_OUTPUT_STREAM_PRIVATE_H */
diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index 206ed30..7062007 100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -676,3 +676,26 @@ _cairo_memory_stream_length (cairo_output_stream_t *base)
 
     return _cairo_array_num_elements (&stream->array);
 }
+
+static cairo_status_t
+null_write (cairo_output_stream_t *base,
+	    const unsigned char *data, unsigned int length)
+{
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_output_stream_t *
+_cairo_null_stream_create (void)
+{
+    cairo_output_stream_t *stream;
+
+    stream = malloc (sizeof *stream);
+    if (stream == NULL) {
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
+    }
+
+    _cairo_output_stream_init (stream, null_write, NULL);
+
+    return stream;
+}
commit 6772efcdf6b6710c839ab58a7218866cc9f409b6
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Thu Sep 11 08:37:02 2008 +0930

    Put user fonts in a separate subset

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index de64c0c..ab51871 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -3722,6 +3722,12 @@ _cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface)
     status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets,
                                                         _cairo_pdf_surface_emit_scaled_font_subset,
                                                         surface);
+    if (status)
+	goto BAIL;
+
+    status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
+						      _cairo_pdf_surface_emit_scaled_font_subset,
+						      surface);
 
 BAIL:
     _cairo_scaled_font_subsets_destroy (surface->font_subsets);
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 9afb694..24b1602 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -610,7 +610,12 @@ _cairo_ps_surface_emit_font_subsets (cairo_ps_surface_t *surface)
     status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets,
                                                         _cairo_ps_surface_emit_scaled_font_subset,
                                                         surface);
+    if (status)
+	goto BAIL;
 
+    status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
+						      _cairo_ps_surface_emit_scaled_font_subset,
+						      surface);
 BAIL:
     _cairo_scaled_font_subsets_destroy (surface->font_subsets);
     surface->font_subsets = NULL;
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index c7991a7..88dedb5 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -282,6 +282,41 @@ _cairo_scaled_font_subsets_foreach_unscaled (cairo_scaled_font_subsets_t
 				             void				      *closure);
 
 /**
+ * _cairo_scaled_font_subsets_foreach_user:
+ * @font_subsets: a #cairo_scaled_font_subsets_t
+ * @font_subset_callback: a function to be called for each font subset
+ * @closure: closure data for the callback function
+ *
+ * Iterate over each unique scaled font subset as created by calls to
+ * _cairo_scaled_font_subsets_map_glyph(). A subset is determined by
+ * unique pairs of (font_id, subset_id) as returned by
+ * _cairo_scaled_font_subsets_map_glyph().
+ *
+ * For each subset, @font_subset_callback will be called and will be
+ * provided with both a #cairo_scaled_font_subset_t object containing
+ * all the glyphs in the subset as well as the value of @closure.
+ *
+ * The #cairo_scaled_font_subset_t object contains the scaled_font,
+ * the font_id, and the subset_id corresponding to all glyphs
+ * belonging to the subset. In addition, it contains an array providing
+ * a mapping between subset glyph indices and the original scaled font
+ * glyph indices.
+ *
+ * The index of the array corresponds to subset_glyph_index values
+ * returned by _cairo_scaled_font_subsets_map_glyph() while the
+ * values of the array correspond to the scaled_font_glyph_index
+ * values passed as input to the same function.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS if successful, or a non-zero
+ * value indicating an error. Possible errors include
+ * %CAIRO_STATUS_NO_MEMORY.
+ **/
+cairo_private cairo_status_t
+_cairo_scaled_font_subsets_foreach_user (cairo_scaled_font_subsets_t		  *font_subsets,
+					 cairo_scaled_font_subset_callback_func_t  font_subset_callback,
+					 void					  *closure);
+
+/**
  * _cairo_scaled_font_subset_create_glyph_names:
  * @font_subsets: a #cairo_scaled_font_subsets_t
  *
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 939808a..9d44ed5 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -62,6 +62,7 @@ typedef struct _cairo_sub_font {
 
     cairo_bool_t is_scaled;
     cairo_bool_t is_composite;
+    cairo_bool_t is_user;
     cairo_scaled_font_subsets_t *parent;
     cairo_scaled_font_t *scaled_font;
     unsigned int font_id;
@@ -265,6 +266,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t	*parent,
 
     sub_font->is_scaled = is_scaled;
     sub_font->is_composite = is_composite;
+    sub_font->is_user = _cairo_font_face_is_user (scaled_font->font_face);
     _cairo_sub_font_init_key (sub_font, scaled_font);
 
     sub_font->parent = parent;
@@ -814,7 +816,8 @@ static cairo_status_t
 _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t              *font_subsets,
                                              cairo_scaled_font_subset_callback_func_t  font_subset_callback,
                                              void				      *closure,
-                                             cairo_bool_t                              is_scaled)
+                                             cairo_bool_t                              is_scaled,
+                                             cairo_bool_t                              is_user)
 {
     cairo_sub_font_collection_t collection;
     cairo_sub_font_t *sub_font;
@@ -848,7 +851,9 @@ _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t
 	sub_font = font_subsets->unscaled_sub_fonts_list;
 
     while (sub_font) {
-	_cairo_sub_font_collect (sub_font, &collection);
+	if (sub_font->is_user == is_user)
+	    _cairo_sub_font_collect (sub_font, &collection);
+
 	sub_font = sub_font->next;
     }
     free (collection.utf8);
@@ -865,6 +870,7 @@ _cairo_scaled_font_subsets_foreach_scaled (cairo_scaled_font_subsets_t		    *fon
     return _cairo_scaled_font_subsets_foreach_internal (font_subsets,
                                                         font_subset_callback,
                                                         closure,
+                                                        FALSE,
                                                         TRUE);
 }
 
@@ -876,9 +882,22 @@ _cairo_scaled_font_subsets_foreach_unscaled (cairo_scaled_font_subsets_t	    *fo
     return _cairo_scaled_font_subsets_foreach_internal (font_subsets,
                                                         font_subset_callback,
                                                         closure,
+                                                        FALSE,
                                                         FALSE);
 }
 
+cairo_status_t
+_cairo_scaled_font_subsets_foreach_user (cairo_scaled_font_subsets_t		  *font_subsets,
+					 cairo_scaled_font_subset_callback_func_t  font_subset_callback,
+					 void					  *closure)
+{
+    return _cairo_scaled_font_subsets_foreach_internal (font_subsets,
+                                                        font_subset_callback,
+                                                        closure,
+                                                        TRUE,
+                                                        TRUE);
+}
+
 static cairo_bool_t
 _cairo_string_equal (const void *key_a, const void *key_b)
 {


More information about the cairo-commit mailing list