[cairo-commit] 3 commits - configure.ac meson.build src/cairo-ft-font.c src/cairo-gl-glyphs.c src/cairo-image-compositor.c src/cairoint.h src/cairo-quartz-font.c src/cairo-scaled-font.c src/cairo-scaled-font-private.h src/cairo-scaled-font-subsets.c src/cairo-script-surface.c src/cairo-surface.c src/cairo-svg-surface.c src/cairo-type1-fallback.c src/cairo-type3-glyph-surface.c src/cairo-user-font.c src/cairo-xcb-surface-render.c src/cairo-xlib-render-compositor.c src/drm src/test-base-compositor-surface.c src/win32

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Sep 16 21:47:27 UTC 2021


 configure.ac                             |    2 -
 meson.build                              |    1 
 src/cairo-ft-font.c                      |   40 ++++++++++++++++++++++++++++--
 src/cairo-gl-glyphs.c                    |    2 +
 src/cairo-image-compositor.c             |    5 +++
 src/cairo-quartz-font.c                  |    3 +-
 src/cairo-scaled-font-private.h          |    9 ++++++
 src/cairo-scaled-font-subsets.c          |    2 +
 src/cairo-scaled-font.c                  |   41 ++++++++++++++++++++++++++++---
 src/cairo-script-surface.c               |    5 +++
 src/cairo-surface.c                      |   13 +++++++--
 src/cairo-svg-surface.c                  |    2 +
 src/cairo-type1-fallback.c               |    3 ++
 src/cairo-type3-glyph-surface.c          |    4 +++
 src/cairo-user-font.c                    |    6 +++-
 src/cairo-xcb-surface-render.c           |    3 ++
 src/cairo-xlib-render-compositor.c       |    2 +
 src/cairoint.h                           |   20 +++++++++++++--
 src/drm/cairo-drm-i915-glyphs.c          |    2 +
 src/drm/cairo-drm-i965-glyphs.c          |    2 +
 src/drm/cairo-drm-intel.c                |    3 +-
 src/test-base-compositor-surface.c       |    1 
 src/win32/cairo-win32-font.c             |    3 +-
 src/win32/cairo-win32-printing-surface.c |    2 +
 24 files changed, 159 insertions(+), 17 deletions(-)

New commits:
commit 994e33215e35e49981dea5b459a9b5b85d4cd1b1
Merge: 4c520fea2 23815978c
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Thu Sep 16 21:47:25 2021 +0000

    Merge branch 'color-font-foreground-color' into 'master'
    
    Support color fonts that use the foreground color
    
    See merge request cairo/cairo!246

commit 23815978cc6eb3b681788ab43c4d8f5979a39869
Merge: fea246310 4c520fea2
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Fri Sep 17 06:25:07 2021 +0930

    Merge branch 'master' into color-font-foreground-color

commit fea24631076f74a3202ba0233be85588ae28db36
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Fri Aug 27 23:12:24 2021 +0930

    Support color fonts that use the foreground color
    
    COLR fonts can have a layer with the same color as the current text
    color. This change passes the current color (if solid) through to
    the font backend where it can be used to render color fonts.
    
    scaled_glyph_lookup checks if the foreground color has changed (for
    glyph that require it) and requests a new color surface if required.
    
    This also fixes a bug where scaled_glyph_lookup would always request a
    color surface for glyphs for glyphs in color fonts that do not have
    color.

diff --git a/configure.ac b/configure.ac
index 0ca0c8e2b..8ff3f35d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -561,7 +561,7 @@ if test "x$use_ft" = "xyes"; then
   LIBS="$LIBS $ft_LIBS"
   CFLAGS="$CFLAGS $ft_CFLAGS"
 
-  AC_CHECK_FUNCS(FT_Get_X11_Font_Format FT_GlyphSlot_Embolden FT_GlyphSlot_Oblique FT_Load_Sfnt_Table FT_Library_SetLcdFilter FT_Get_Var_Design_Coordinates FT_Done_MM_Var)
+  AC_CHECK_FUNCS(FT_Get_X11_Font_Format FT_GlyphSlot_Embolden FT_GlyphSlot_Oblique FT_Load_Sfnt_Table FT_Library_SetLcdFilter FT_Get_Var_Design_Coordinates FT_Done_MM_Var FT_Palette_Set_Foreground_Color)
 
   AC_MSG_CHECKING(for FT_HAS_COLOR)
   AC_LINK_IFELSE([AC_LANG_PROGRAM([
diff --git a/meson.build b/meson.build
index 7a0506712..6236d743b 100644
--- a/meson.build
+++ b/meson.build
@@ -330,6 +330,7 @@ if freetype_dep.found()
     'FT_Library_SetLcdFilter',
     'FT_Get_Var_Design_Coordinates',
     'FT_Done_MM_Var',
+    'FT_Palette_Set_Foreground_Color',
   ]
 
   if freetype_dep.type_name() == 'internal'
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index adfb445df..66300dd03 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -2479,6 +2479,7 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t     *scaled_font,
 				     cairo_scaled_glyph_t	*scaled_glyph,
 				     cairo_scaled_glyph_info_t	 info,
 				     FT_Face face,
+				     const cairo_color_t        *foreground_color,
 				     cairo_bool_t vertical_layout,
 				     int load_flags)
 {
@@ -2486,11 +2487,40 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t     *scaled_font,
     FT_GlyphSlot glyph;
     cairo_status_t status;
     cairo_image_surface_t	*surface;
+    cairo_bool_t uses_foreground_color = FALSE;
 
     if (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) {
 	if (!unscaled->have_color)
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 
+#ifdef HAVE_FT_PALETTE_SET_FOREGROUND_COLOR
+	FT_LayerIterator  iterator;
+	FT_UInt layer_glyph_index;
+	FT_UInt layer_color_index;
+	FT_Color color;
+
+	/* Check if there is a layer that uses the foreground color */
+	iterator.p  = NULL;
+	while (FT_Get_Color_Glyph_Layer(face,
+					_cairo_scaled_glyph_index(scaled_glyph),
+					&layer_glyph_index,
+					&layer_color_index,
+					&iterator)) {
+	    if (layer_color_index == 0xFFFF) {
+		uses_foreground_color = TRUE;
+		break;
+	    }
+	}
+
+	if (uses_foreground_color) {
+	    color.red = (FT_Byte)(foreground_color->red * 0xFF);
+	    color.green = (FT_Byte)(foreground_color->green * 0xFF);
+	    color.blue = (FT_Byte)(foreground_color->blue * 0xFF);
+	    color.alpha = (FT_Byte)(foreground_color->alpha * 0xFF);
+	    FT_Palette_Set_Foreground_Color (face, color);
+	}
+#endif
+
         load_flags &= ~FT_LOAD_MONOCHROME;
 	/* clear load target mode */
 	load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(load_flags)));
@@ -2534,11 +2564,14 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t     *scaled_font,
 	!pixman_image_get_component_alpha (surface->pixman_image)) {
 	_cairo_scaled_glyph_set_color_surface (scaled_glyph,
 					       &scaled_font->base,
-					       surface);
+					       surface,
+					       uses_foreground_color);
     } else {
 	_cairo_scaled_glyph_set_surface (scaled_glyph,
 					 &scaled_font->base,
 					 surface);
+	if (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)
+	    scaled_glyph->not_color_glyph = TRUE;
     }
 
     return status;
@@ -2547,7 +2580,8 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t     *scaled_font,
 static cairo_int_status_t
 _cairo_ft_scaled_glyph_init (void			*abstract_font,
 			     cairo_scaled_glyph_t	*scaled_glyph,
-			     cairo_scaled_glyph_info_t	 info)
+			     cairo_scaled_glyph_info_t	 info,
+			     const cairo_color_t        *foreground_color)
 {
     cairo_text_extents_t    fs_metrics;
     cairo_ft_scaled_font_t *scaled_font = abstract_font;
@@ -2698,6 +2732,7 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
 						      scaled_glyph,
 						      CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE,
 						      face,
+						      foreground_color,
 						      vertical_layout,
 						      load_flags);
 	if (unlikely (status))
@@ -2709,6 +2744,7 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
 						      scaled_glyph,
 						      CAIRO_SCALED_GLYPH_INFO_SURFACE,
 						      face,
+						      NULL, /* foreground color */
 						      vertical_layout,
 						      load_flags);
 	if (unlikely (status))
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 5923af441..0384dbf24 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* Cairo - a vector graphics library with display and print output
  *
  * Copyright © 2009 Chris Wilson
@@ -269,6 +270,7 @@ render_glyphs (cairo_gl_surface_t *dst,
 	status = _cairo_scaled_glyph_lookup (info->font,
 					     info->glyphs[i].index,
 					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
+					     NULL, /* foreground color */
 					     &scaled_glyph);
 	if (unlikely (status))
 	    goto FINISH;
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index 0ded5388e..0a293f05d 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -909,6 +909,7 @@ composite_glyphs (void				*_dst,
 	    CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex);
 	    status = _cairo_scaled_glyph_lookup (info->font, index,
 						 CAIRO_SCALED_GLYPH_INFO_SURFACE,
+						 NULL, /* foreground color */
 						 &scaled_glyph);
 	    CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex);
 
@@ -997,6 +998,7 @@ composite_one_glyph (void				*_dst,
     status = _cairo_scaled_glyph_lookup (info->font,
 					 info->glyphs[0].index,
 					 CAIRO_SCALED_GLYPH_INFO_SURFACE,
+					 NULL, /* foreground color */
 					 &scaled_glyph);
 
     if (unlikely (status))
@@ -1059,6 +1061,7 @@ composite_glyphs_via_mask (void				*_dst,
     status = _cairo_scaled_glyph_lookup (info->font,
 					 info->glyphs[0].index,
 					 CAIRO_SCALED_GLYPH_INFO_SURFACE,
+					 NULL, /* foreground color */
 					 &scaled_glyph);
     if (unlikely (status)) {
 	pixman_image_unref (white);
@@ -1105,6 +1108,7 @@ composite_glyphs_via_mask (void				*_dst,
 	{
 	    status = _cairo_scaled_glyph_lookup (info->font, glyph_index,
 						 CAIRO_SCALED_GLYPH_INFO_SURFACE,
+						 NULL, /* foreground color */
 						 &scaled_glyph);
 
 	    if (unlikely (status)) {
@@ -1231,6 +1235,7 @@ composite_glyphs (void				*_dst,
 	{
 	    status = _cairo_scaled_glyph_lookup (info->font, glyph_index,
 						 CAIRO_SCALED_GLYPH_INFO_SURFACE,
+						 NULL, /* foreground color */
 						 &scaled_glyph);
 
 	    if (unlikely (status))
diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c
index 8cb71434f..77a9d6a55 100644
--- a/src/cairo-quartz-font.c
+++ b/src/cairo-quartz-font.c
@@ -743,7 +743,8 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
 static cairo_int_status_t
 _cairo_quartz_scaled_glyph_init (void *abstract_font,
 				 cairo_scaled_glyph_t *scaled_glyph,
-				 cairo_scaled_glyph_info_t info)
+				 cairo_scaled_glyph_info_t info,
+				 const cairo_color_t *foreground_color)
 {
     cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t *) abstract_font;
     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
diff --git a/src/cairo-scaled-font-private.h b/src/cairo-scaled-font-private.h
index 4bacb1a01..42e9b0913 100644
--- a/src/cairo-scaled-font-private.h
+++ b/src/cairo-scaled-font-private.h
@@ -147,7 +147,14 @@ struct _cairo_scaled_glyph {
     void		   *dev_private;
     cairo_list_t            dev_privates;
 
-    cairo_bool_t            has_color;
+    cairo_color_t           foreground_color;   /* only used for color glyphs */
+    /* TRUE if the color_surface used the foreground_color to render. */
+    unsigned                uses_foreground_color : 1;
+
+    /* TRUE if this is not a color glyph, FALSE if is a color glyph or unknown.  */
+    unsigned                not_color_glyph : 1;
+
+    unsigned                has_color : 1;
 };
 
 struct _cairo_scaled_glyph_private {
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 0ae41aebe..94a7aae26 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -513,6 +513,7 @@ _cairo_sub_font_add_glyph (cairo_sub_font_t	   *sub_font,
     status = _cairo_scaled_glyph_lookup (sub_font->scaled_font,
 					 scaled_font_glyph_index,
 					 CAIRO_SCALED_GLYPH_INFO_METRICS,
+					 NULL, /* foreground color */
 					 &scaled_glyph);
     assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
     if (unlikely (status)) {
@@ -890,6 +891,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t	*subsets,
 	status = _cairo_scaled_glyph_lookup (scaled_font,
 					     scaled_font_glyph_index,
 					     CAIRO_SCALED_GLYPH_INFO_PATH,
+                                             NULL, /* foreground color */
 					     &scaled_glyph);
 	_cairo_scaled_font_thaw_cache (scaled_font);
     }
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 65c1d2595..ef0db0506 100755
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1611,6 +1611,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t   *scaled_font,
 	status = _cairo_scaled_glyph_lookup (scaled_font,
 					     glyphs[i].index,
 					     CAIRO_SCALED_GLYPH_INFO_METRICS,
+					     NULL, /* foreground color */
 					     &scaled_glyph);
 	if (unlikely (status)) {
 	    status = _cairo_scaled_font_set_error (scaled_font, status);
@@ -1732,6 +1733,7 @@ cairo_scaled_font_text_to_glyphs_internal_cached (cairo_scaled_font_t		 *scaled_
 	    status = _cairo_scaled_glyph_lookup (scaled_font,
 						 g,
 						 CAIRO_SCALED_GLYPH_INFO_METRICS,
+						 NULL, /* foreground color */
 						 &scaled_glyph);
 	    if (unlikely (status))
 		return status;
@@ -1792,6 +1794,7 @@ cairo_scaled_font_text_to_glyphs_internal_uncached (cairo_scaled_font_t	 *scaled
 	    status = _cairo_scaled_glyph_lookup (scaled_font,
 					     g,
 					     CAIRO_SCALED_GLYPH_INFO_METRICS,
+					     NULL, /* foreground color */
 					     &scaled_glyph);
 	    if (unlikely (status))
 		return status;
@@ -2176,6 +2179,7 @@ _cairo_scaled_font_single_glyph_device_extents (cairo_scaled_font_t	 *scaled_fon
     status = _cairo_scaled_glyph_lookup (scaled_font,
 					 glyph->index,
 					 CAIRO_SCALED_GLYPH_INFO_METRICS,
+					 NULL, /* foreground color */
 					 &scaled_glyph);
     if (likely (status == CAIRO_STATUS_SUCCESS)) {
 	cairo_bool_t round_xy = _cairo_font_options_get_round_glyph_positions (&scaled_font->options) == CAIRO_ROUND_GLYPH_POS_ON;
@@ -2246,6 +2250,7 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t	 *scaled_font,
 	    status = _cairo_scaled_glyph_lookup (scaled_font,
 						 glyphs[i].index,
 						 CAIRO_SCALED_GLYPH_INFO_METRICS,
+						 NULL, /* foreground color */
 						 &scaled_glyph);
 	    if (unlikely (status))
 		break;
@@ -2402,6 +2407,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t	*scaled_font,
 	status = _cairo_scaled_glyph_lookup (scaled_font,
 					     glyphs[i].index,
 					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
+					     NULL, /* foreground color */
 					     &scaled_glyph);
 
 	if (unlikely (status))
@@ -2656,6 +2662,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
 	status = _cairo_scaled_glyph_lookup (scaled_font,
 					     glyphs[i].index,
 					     CAIRO_SCALED_GLYPH_INFO_PATH,
+					     NULL, /* foreground color */
 					     &scaled_glyph);
 	if (status == CAIRO_INT_STATUS_SUCCESS) {
 	    status = _cairo_path_fixed_append (path,
@@ -2670,6 +2677,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
 	    status = _cairo_scaled_glyph_lookup (scaled_font,
 						 glyphs[i].index,
 						 CAIRO_SCALED_GLYPH_INFO_SURFACE,
+						 NULL, /* foreground color */
 						 &scaled_glyph);
 	    if (unlikely (status))
 		goto BAIL;
@@ -2830,7 +2838,8 @@ _cairo_scaled_glyph_set_recording_surface (cairo_scaled_glyph_t *scaled_glyph,
 void
 _cairo_scaled_glyph_set_color_surface (cairo_scaled_glyph_t *scaled_glyph,
 	                               cairo_scaled_font_t *scaled_font,
-	                               cairo_image_surface_t *surface)
+	                               cairo_image_surface_t *surface,
+				       cairo_bool_t uses_foreground_color)
 {
     if (scaled_glyph->color_surface != NULL)
 	cairo_surface_destroy (&scaled_glyph->color_surface->base);
@@ -2838,6 +2847,7 @@ _cairo_scaled_glyph_set_color_surface (cairo_scaled_glyph_t *scaled_glyph,
     /* sanity check the backend glyph contents */
     _cairo_debug_check_image_surface_is_defined (&surface->base);
     scaled_glyph->color_surface = surface;
+    scaled_glyph->uses_foreground_color = uses_foreground_color;
 
     if (surface != NULL)
 	scaled_glyph->has_info |= CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE;
@@ -2956,6 +2966,8 @@ _cairo_scaled_font_free_last_glyph (cairo_scaled_font_t *scaled_font,
  * @index: the glyph to create
  * @info: a #cairo_scaled_glyph_info_t marking which portions of
  * the glyph should be filled in.
+ * @foreground_color - foreground color to use when rendering color fonts. Use NULL
+ * if not requesting CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE or foreground color is unknown.
  * @scaled_glyph_ret: a #cairo_scaled_glyph_t where the glyph
  * is returned.
  *
@@ -2976,11 +2988,14 @@ _cairo_scaled_font_free_last_glyph (cairo_scaled_font_t *scaled_font,
  *  %CAIRO_SCALED_GLYPH_INFO_METRICS - glyph metrics and bounding box
  *  %CAIRO_SCALED_GLYPH_INFO_SURFACE - surface holding glyph image
  *  %CAIRO_SCALED_GLYPH_INFO_PATH - path holding glyph outline in device space
+ *  %CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE - surface holding recording of glyph
+ *  %CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE - surface holding color glyph image
  **/
 cairo_int_status_t
 _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
 			    unsigned long index,
 			    cairo_scaled_glyph_info_t info,
+			    const cairo_color_t   *foreground_color,
 			    cairo_scaled_glyph_t **scaled_glyph_ret)
 {
     cairo_int_status_t		 status = CAIRO_INT_STATUS_SUCCESS;
@@ -2998,6 +3013,9 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
     if (CAIRO_INJECT_FAULT ())
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
+    if (foreground_color == NULL)
+	foreground_color = CAIRO_COLOR_BLACK;
+
     /*
      * Check cache for glyph
      */
@@ -3016,7 +3034,8 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
 	status =
 	    scaled_font->backend->scaled_glyph_init (scaled_font,
 						     scaled_glyph,
-						     info | CAIRO_SCALED_GLYPH_INFO_METRICS);
+						     info | CAIRO_SCALED_GLYPH_INFO_METRICS,
+						     foreground_color);
 	if (unlikely (status)) {
 	    _cairo_scaled_font_free_last_glyph (scaled_font, scaled_glyph);
 	    goto err;
@@ -3035,10 +3054,26 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
      * already has the requested data and amend it if not
      */
     need_info = info & ~scaled_glyph->has_info;
+
+    /* If this is not a color glyph, don't try loading the color surface again. */
+    if ((need_info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) && scaled_glyph->not_color_glyph)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* If requesting a color surface for a glyph that has used the
+     * foreground color to render the color_surface, and the
+     * foreground color has changed, request a new image. */
+    if ((info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) &&
+	scaled_glyph->uses_foreground_color &&
+	!_cairo_color_equal (foreground_color, &scaled_glyph->foreground_color))
+    {
+	need_info |= CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE;
+    }
+
     if (need_info) {
 	status = scaled_font->backend->scaled_glyph_init (scaled_font,
 							  scaled_glyph,
-							  need_info);
+							  need_info,
+							  foreground_color);
 	if (unlikely (status))
 	    goto err;
 
diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c
index 9d6b954c1..ca9bafbb7 100644
--- a/src/cairo-script-surface.c
+++ b/src/cairo-script-surface.c
@@ -3194,6 +3194,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface,
 	status = _cairo_scaled_glyph_lookup (scaled_font,
 					     glyphs[n].index,
 					     CAIRO_SCALED_GLYPH_INFO_METRICS,
+                                             NULL, /* foreground color */
 					     &scaled_glyph);
 	if (unlikely (status))
 	    break;
@@ -3204,6 +3205,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface,
 	status = _cairo_scaled_glyph_lookup (scaled_font,
 					     glyphs[n].index,
 					     CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
+                                             NULL, /* foreground color */
 					     &scaled_glyph);
 	if (_cairo_status_is_error (status))
 	    break;
@@ -3229,6 +3231,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface,
 	status = _cairo_scaled_glyph_lookup (scaled_font,
 					     glyphs[n].index,
 					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
+                                             NULL, /* foreground color */
 					     &scaled_glyph);
 	if (_cairo_status_is_error (status))
 	    break;
@@ -3411,6 +3414,7 @@ _cairo_script_surface_show_text_glyphs (void			    *abstract_surface,
 	    status = _cairo_scaled_glyph_lookup (scaled_font,
 						 glyphs[n].index,
 						 CAIRO_SCALED_GLYPH_INFO_METRICS,
+						 NULL, /* foreground color */
 						 &scaled_glyph);
 	    if (unlikely (status)) {
 		_cairo_scaled_font_thaw_cache (scaled_font);
@@ -3434,6 +3438,7 @@ _cairo_script_surface_show_text_glyphs (void			    *abstract_surface,
 	status = _cairo_scaled_glyph_lookup (scaled_font,
 					     glyphs[n].index,
 					     CAIRO_SCALED_GLYPH_INFO_METRICS,
+                                             NULL, /* foreground color */
 					     &scaled_glyph);
 	if (unlikely (status)) {
 	    _cairo_scaled_font_thaw_cache (scaled_font);
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 380759db9..eea7d6030 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -2602,6 +2602,7 @@ slim_hidden_def (cairo_surface_has_show_text_glyphs);
 
 static inline cairo_int_status_t
 ensure_scaled_glyph (cairo_scaled_font_t   *scaled_font,
+		     cairo_color_t         *foreground_color,
                      cairo_scaled_glyph_t **glyph_cache,
                      cairo_glyph_t         *glyph,
                      cairo_scaled_glyph_t **scaled_glyph)
@@ -2615,12 +2616,14 @@ ensure_scaled_glyph (cairo_scaled_font_t   *scaled_font,
         status = _cairo_scaled_glyph_lookup (scaled_font,
                                              glyph->index,
                                              CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE,
+					     foreground_color,
                                              scaled_glyph);
 	if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 	    /* If the color surface not available, ensure scaled_glyph is not NULL. */
 	    status = _cairo_scaled_glyph_lookup (scaled_font,
 						 glyph->index,
 						 CAIRO_SCALED_GLYPH_INFO_METRICS,
+						 NULL, /* foreground color */
 						 scaled_glyph);
 	}
         if (unlikely (status))
@@ -2693,6 +2696,10 @@ composite_color_glyphs (cairo_surface_t             *surface,
     int byte_pos = 0;
     int gp;
     cairo_scaled_glyph_t *glyph_cache[GLYPH_CACHE_SIZE];
+    cairo_color_t *foreground_color = NULL;
+
+    if (source->type == CAIRO_PATTERN_TYPE_SOLID)
+	foreground_color = &((cairo_solid_pattern_t *) source)->color;
 
     memset (glyph_cache, 0, sizeof (glyph_cache));
 
@@ -2714,7 +2721,7 @@ composite_color_glyphs (cairo_surface_t             *surface,
                 else
                     gp = glyph_pos + j;
 
-                status = ensure_scaled_glyph (scaled_font, glyph_cache,
+                status = ensure_scaled_glyph (scaled_font, foreground_color, glyph_cache,
                                               &glyphs[gp], &scaled_glyph);
                 if (unlikely (status))
                     goto UNLOCK;
@@ -2745,7 +2752,7 @@ composite_color_glyphs (cairo_surface_t             *surface,
                 else
                     gp = glyph_pos + j;
 
-                status = ensure_scaled_glyph (scaled_font, glyph_cache,
+                status = ensure_scaled_glyph (scaled_font, foreground_color, glyph_cache,
                                               &glyphs[gp], &scaled_glyph);
                 if (unlikely (status))
                     goto UNLOCK;
@@ -2774,7 +2781,7 @@ composite_color_glyphs (cairo_surface_t             *surface,
     } else {
 
        for (glyph_pos = 0; glyph_pos < *num_glyphs; glyph_pos++) {
-           status = ensure_scaled_glyph (scaled_font, glyph_cache,
+           status = ensure_scaled_glyph (scaled_font, foreground_color, glyph_cache,
                                          &glyphs[glyph_pos], &scaled_glyph);
            if (unlikely (status))
                goto UNLOCK;
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 80f3a0eb0..c6d9382b3 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -1326,6 +1326,7 @@ _cairo_svg_document_emit_outline_glyph_data (cairo_svg_document_t *document,
     status = _cairo_scaled_glyph_lookup (scaled_font,
 					 glyph_index,
 					 CAIRO_SCALED_GLYPH_INFO_METRICS | CAIRO_SCALED_GLYPH_INFO_PATH,
+					 NULL, /* foreground color */
 					 &scaled_glyph);
     if (unlikely (status)) {
 	return status;
@@ -1357,6 +1358,7 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
     status = _cairo_scaled_glyph_lookup (scaled_font,
 					 glyph_index,
 					 CAIRO_SCALED_GLYPH_INFO_METRICS | CAIRO_SCALED_GLYPH_INFO_SURFACE,
+					 NULL, /* foreground color */
 					 &scaled_glyph);
     if (unlikely (status)) {
 	return status;
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index 0b8e66cd0..3a44c4666 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2006 Red Hat, Inc
@@ -354,6 +355,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t      *font,
 					 glyph_index,
 					 CAIRO_SCALED_GLYPH_INFO_METRICS|
 					 CAIRO_SCALED_GLYPH_INFO_PATH,
+					 NULL, /* foreground color */
 					 &scaled_glyph);
 
     /* It is ok for the .notdef glyph to not have a path available. We
@@ -363,6 +365,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t      *font,
 	status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
 					     glyph_index,
 					     CAIRO_SCALED_GLYPH_INFO_METRICS,
+                                             NULL, /* foreground color */
 					     &scaled_glyph);
     }
     if (unlikely (status))
diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c
index 6b2102319..05ef417dc 100644
--- a/src/cairo-type3-glyph-surface.c
+++ b/src/cairo-type3-glyph-surface.c
@@ -373,6 +373,7 @@ _cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *sur
 					 glyph_index,
 					 CAIRO_SCALED_GLYPH_INFO_METRICS |
 					 CAIRO_SCALED_GLYPH_INFO_SURFACE,
+					 NULL, /* foreground color */
 					 &scaled_glyph);
     if (unlikely (status))
 	return status;
@@ -428,6 +429,7 @@ _cairo_type3_glyph_surface_analyze_glyph (void		     *abstract_surface,
     status = _cairo_scaled_glyph_lookup (surface->scaled_font,
 					 glyph_index,
 					 CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
+					 NULL, /* foreground color */
 					 &scaled_glyph);
 
     if (_cairo_int_status_is_error (status))
@@ -480,11 +482,13 @@ _cairo_type3_glyph_surface_emit_glyph (void		     *abstract_surface,
 					 glyph_index,
 					 CAIRO_SCALED_GLYPH_INFO_METRICS |
 					 CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
+					 NULL, /* foreground color */
 					 &scaled_glyph);
     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 	status = _cairo_scaled_glyph_lookup (surface->scaled_font,
 					     glyph_index,
 					     CAIRO_SCALED_GLYPH_INFO_METRICS,
+					     NULL, /* foreground color */
 					     &scaled_glyph);
 	if (status == CAIRO_INT_STATUS_SUCCESS)
 	    status = CAIRO_INT_STATUS_IMAGE_FALLBACK;
diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index 04c9ee699..47b9f0422 100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -144,7 +144,8 @@ _cairo_user_scaled_font_create_recording_context (const cairo_user_scaled_font_t
 static cairo_int_status_t
 _cairo_user_scaled_glyph_init (void			 *abstract_font,
 			       cairo_scaled_glyph_t	 *scaled_glyph,
-			       cairo_scaled_glyph_info_t  info)
+			       cairo_scaled_glyph_info_t  info,
+			       const cairo_color_t       *foreground_color)
 {
     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_user_scaled_font_t *scaled_font = abstract_font;
@@ -300,7 +301,8 @@ _cairo_user_scaled_glyph_init (void			 *abstract_font,
         if (scaled_glyph->has_color && (info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) {
             _cairo_scaled_glyph_set_color_surface (scaled_glyph,
                                                    &scaled_font->base,
-                                                   (cairo_image_surface_t *)surface);
+                                                   (cairo_image_surface_t *)surface,
+						   FALSE);
         }
     }
 
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index a1eaad9a5..5993aa378 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -3994,6 +3994,7 @@ _can_composite_glyphs (cairo_xcb_surface_t *dst,
 	    status = _cairo_scaled_glyph_lookup (scaled_font,
 						 glyphs->index,
 						 CAIRO_SCALED_GLYPH_INFO_METRICS,
+                                                 NULL, /* foreground color */
 						 &glyph);
 	    if (unlikely (status))
 		break;
@@ -4399,6 +4400,7 @@ _cairo_xcb_surface_add_glyph (cairo_xcb_connection_t *connection,
 					     glyph_index,
 					     CAIRO_SCALED_GLYPH_INFO_METRICS |
 					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
+                                             NULL, /* foreground color */
 					     scaled_glyph_out);
 	if (unlikely (status))
 	    return status;
@@ -4692,6 +4694,7 @@ _composite_glyphs (void				*closure,
 	    status = _cairo_scaled_glyph_lookup (info->font,
 						 glyph_index,
 						 CAIRO_SCALED_GLYPH_INFO_METRICS,
+                                                 NULL, /* foreground color */
 						 &glyph);
 	    if (unlikely (status)) {
 		cairo_surface_destroy (&src->base);
diff --git a/src/cairo-xlib-render-compositor.c b/src/cairo-xlib-render-compositor.c
index bf8d20546..c872f5680 100644
--- a/src/cairo-xlib-render-compositor.c
+++ b/src/cairo-xlib-render-compositor.c
@@ -1204,6 +1204,7 @@ _cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display,
 					     glyph_index,
 					     CAIRO_SCALED_GLYPH_INFO_METRICS |
 					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
+                                             NULL, /* foreground color */
 					     pscaled_glyph);
 	if (unlikely (status))
 	    return status;
@@ -1619,6 +1620,7 @@ composite_glyphs (void				*surface,
 	status = _cairo_scaled_glyph_lookup (info->font,
 					     glyphs[i].index,
 					     CAIRO_SCALED_GLYPH_INFO_METRICS,
+                                             NULL, /* foreground color */
 					     &glyph);
 	if (unlikely (status))
 	    return status;
diff --git a/src/cairoint.h b/src/cairoint.h
index 1e0cb4bf1..c5872b8cc 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -519,10 +519,24 @@ struct _cairo_scaled_font_backend {
     void
     (*fini)		(void			*scaled_font);
 
+/**
+ * Get the requested glyph info.
+ * @scaled_font: a #cairo_scaled_font_t
+ * @scaled_glyph: a #cairo_scaled_glyph_t the glyph
+ * @info: a #cairo_scaled_glyph_info_t which information to retreive
+ *  %CAIRO_SCALED_GLYPH_INFO_METRICS - glyph metrics and bounding box
+ *  %CAIRO_SCALED_GLYPH_INFO_SURFACE - surface holding glyph image
+ *  %CAIRO_SCALED_GLYPH_INFO_PATH - path holding glyph outline in device space
+ *  %CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE - surface holding recording of glyph
+ *  %CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE - surface holding color glyph image
+ * @foreground_color - foreground color to use when rendering color fonts. Use NULL
+ * if not requesting CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE or foreground color is unknown.
+ */
     cairo_warn cairo_int_status_t
     (*scaled_glyph_init)	(void			     *scaled_font,
 				 cairo_scaled_glyph_t	     *scaled_glyph,
-				 cairo_scaled_glyph_info_t    info);
+				 cairo_scaled_glyph_info_t    info,
+                                 const cairo_color_t         *foreground_color);
 
     /* A backend only needs to implement this or ucs4_to_index(), not
      * both. This allows the backend to do something more sophisticated
@@ -1284,12 +1298,14 @@ _cairo_scaled_glyph_set_recording_surface (cairo_scaled_glyph_t *scaled_glyph,
 cairo_private void
 _cairo_scaled_glyph_set_color_surface (cairo_scaled_glyph_t *scaled_glyph,
 		                       cairo_scaled_font_t *scaled_font,
-		                       cairo_image_surface_t *surface);
+		                       cairo_image_surface_t *surface,
+                                       cairo_bool_t uses_foreground_color);
 
 cairo_private cairo_int_status_t
 _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
 			    unsigned long index,
 			    cairo_scaled_glyph_info_t info,
+                            const cairo_color_t   *foreground_color,
 			    cairo_scaled_glyph_t **scaled_glyph_ret);
 
 cairo_private double
diff --git a/src/drm/cairo-drm-i915-glyphs.c b/src/drm/cairo-drm-i915-glyphs.c
index 3b0efc248..6fdcc0d2b 100644
--- a/src/drm/cairo-drm-i915-glyphs.c
+++ b/src/drm/cairo-drm-i915-glyphs.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2009 Intel Corporation
@@ -447,6 +448,7 @@ i915_surface_glyphs (void			*abstract_surface,
 	    status = _cairo_scaled_glyph_lookup (scaled_font,
 						 glyphs[i].index,
 						 CAIRO_SCALED_GLYPH_INFO_METRICS,
+						 NULL, /* foreground color */
 						 &scaled_glyph);
 	    if (unlikely (status))
 		goto FINISH;
diff --git a/src/drm/cairo-drm-i965-glyphs.c b/src/drm/cairo-drm-i965-glyphs.c
index 1ef0a6f59..22ace66e3 100644
--- a/src/drm/cairo-drm-i965-glyphs.c
+++ b/src/drm/cairo-drm-i965-glyphs.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2009 Intel Corporation
@@ -366,6 +367,7 @@ i965_surface_glyphs (void			*abstract_surface,
 	    status = _cairo_scaled_glyph_lookup (scaled_font,
 						 g[i].index,
 						 CAIRO_SCALED_GLYPH_INFO_METRICS,
+						 NULL, /* foreground color */
 						 &scaled_glyph);
 	    if (unlikely (status))
 		goto FINISH;
diff --git a/src/drm/cairo-drm-intel.c b/src/drm/cairo-drm-intel.c
index e45f999ec..ce6c38040 100644
--- a/src/drm/cairo-drm-intel.c
+++ b/src/drm/cairo-drm-intel.c
@@ -994,7 +994,8 @@ intel_get_glyph (intel_device_t *device,
 	status =
 	    scaled_font->backend->scaled_glyph_init (scaled_font,
 						     scaled_glyph,
-						     CAIRO_SCALED_GLYPH_INFO_SURFACE);
+						     CAIRO_SCALED_GLYPH_INFO_SURFACE,
+                                                     NULL);
 	if (unlikely (status))
 	    return status;
 
diff --git a/src/test-base-compositor-surface.c b/src/test-base-compositor-surface.c
index ff84b10af..00e3d0c56 100644
--- a/src/test-base-compositor-surface.c
+++ b/src/test-base-compositor-surface.c
@@ -734,6 +734,7 @@ composite_glyphs (cairo_image_surface_t	*dst,
 
 	status = _cairo_scaled_glyph_lookup (info->font, glyph_index,
 					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
+					     NULL, /* foreground color */
 					     &scaled_glyph);
 
 	if (unlikely (status))
diff --git a/src/win32/cairo-win32-font.c b/src/win32/cairo-win32-font.c
index 792e329d4..eb4ba7a22 100644
--- a/src/win32/cairo-win32-font.c
+++ b/src/win32/cairo-win32-font.c
@@ -715,6 +715,7 @@ _cairo_win32_scaled_font_type1_text_to_glyphs (cairo_win32_scaled_font_t *scaled
 	status = _cairo_scaled_glyph_lookup (&scaled_font->base,
 					     glyph_indices[i],
 					     CAIRO_SCALED_GLYPH_INFO_METRICS,
+					     NULL, /* foreground color */
 					     &scaled_glyph);
 	if (status) {
 	    free (*glyphs);
@@ -1319,7 +1320,8 @@ _draw_glyphs_on_surface (cairo_win32_surface_t     *surface,
 static cairo_int_status_t
 _cairo_win32_scaled_font_glyph_init (void		       *abstract_font,
 				     cairo_scaled_glyph_t      *scaled_glyph,
-				     cairo_scaled_glyph_info_t  info)
+				     cairo_scaled_glyph_info_t  info,
+				     const cairo_color_t       *foreground_color)
 {
     cairo_win32_scaled_font_t *scaled_font = abstract_font;
     cairo_status_t status;
diff --git a/src/win32/cairo-win32-printing-surface.c b/src/win32/cairo-win32-printing-surface.c
index 36d17e960..19b7f9e93 100644
--- a/src/win32/cairo-win32-printing-surface.c
+++ b/src/win32/cairo-win32-printing-surface.c
@@ -1865,6 +1865,7 @@ _cairo_win32_printing_surface_show_glyphs (void                 *abstract_surfac
 	    status = _cairo_scaled_glyph_lookup (scaled_font,
 						 glyphs[i].index,
 						 CAIRO_SCALED_GLYPH_INFO_PATH,
+						 NULL, /* foreground color */
 						 &scaled_glyph);
 	    if (status)
                 break;
@@ -1919,6 +1920,7 @@ _cairo_win32_printing_surface_show_glyphs (void                 *abstract_surfac
 	status = _cairo_scaled_glyph_lookup (scaled_font,
 					     glyphs[i].index,
 					     CAIRO_SCALED_GLYPH_INFO_PATH,
+					     NULL, /* foreground color */
 					     &scaled_glyph);
 	if (status)
 	    break;


More information about the cairo-commit mailing list