[cairo] [PATCH 2/6] Support loading color glyphs with freetype

matthias.clasen at gmail.com matthias.clasen at gmail.com
Sat Apr 9 03:22:29 UTC 2016


From: Matthias Clasen <mclasen at redhat.com>

Use the FT_LOAD_COLOR flag to instruct freetype to load embedded
PNGs without converting them to grayscale. We always load both
the color and regular surface when we are loading surfaces.
---
 src/cairo-ft-font.c | 47 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index a0c7beb..3e3416b 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -2238,7 +2238,8 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
     load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
 
     if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 &&
-	(info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0)
+	(info & (CAIRO_SCALED_GLYPH_INFO_SURFACE |
+                 CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) == 0)
 	load_flags |= FT_LOAD_NO_BITMAP;
 
     /*
@@ -2251,19 +2252,10 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
     }
 
 #ifdef FT_LOAD_COLOR
-    /* Color-glyph support:
-     *
-     * This flags needs plumbing through fontconfig (does it?), and
-     * maybe we should cache color and grayscale bitmaps separately
-     * such that users of the font (ie. the surface) can choose which
-     * version to use based on target content type.
-     *
-     * Moreover, none of our backends and compositors currently support
-     * color glyphs.  As such, this is currently disabled.
-     */
-    /* load_flags |= FT_LOAD_COLOR; */
+     load_flags |= FT_LOAD_COLOR;
 #endif
 
+ LOAD:
     error = FT_Load_Glyph (face,
 			   _cairo_scaled_glyph_index(scaled_glyph),
 			   load_flags);
@@ -2389,7 +2381,8 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
 					 &fs_metrics);
     }
 
-    if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
+    if ((info & (CAIRO_SCALED_GLYPH_INFO_SURFACE |
+                 CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) != 0) {
 	cairo_image_surface_t	*surface;
 
 	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
@@ -2410,11 +2403,30 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
 	if (unlikely (status))
 	    goto FAIL;
 
-	_cairo_scaled_glyph_set_surface (scaled_glyph,
-					 &scaled_font->base,
-					 surface);
+        if (pixman_image_get_format (surface->pixman_image) == PIXMAN_a8r8g8b8 &&
+            !pixman_image_get_component_alpha (surface->pixman_image))
+	        _cairo_scaled_glyph_set_color_surface (scaled_glyph,
+					               &scaled_font->base,
+					               surface);
+       else
+	        _cairo_scaled_glyph_set_surface (scaled_glyph,
+					         &scaled_font->base,
+					         surface);
     }
 
+#ifdef FT_LOAD_COLOR
+    if ((info & (CAIRO_SCALED_GLYPH_INFO_SURFACE | CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) != 0 &&
+        (scaled_glyph->has_info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0) {
+        /*
+         * A kludge -- load again, without color.
+         * No need to load the metrics again, though
+         */
+        info &= ~(CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE | CAIRO_SCALED_GLYPH_INFO_METRICS);
+        load_flags &= ~FT_LOAD_COLOR;
+        goto LOAD;
+    }
+#endif
+
     if (info & CAIRO_SCALED_GLYPH_INFO_PATH) {
 	cairo_path_fixed_t *path = NULL; /* hide compiler warning */
 
@@ -2422,7 +2434,8 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
 	 * A kludge -- the above code will trash the outline,
 	 * so reload it. This will probably never occur though
 	 */
-	if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
+	if ((info & (CAIRO_SCALED_GLYPH_INFO_SURFACE |
+                     CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) != 0) {
 	    error = FT_Load_Glyph (face,
 				   _cairo_scaled_glyph_index(scaled_glyph),
 				   load_flags | FT_LOAD_NO_BITMAP);
-- 
2.7.3



More information about the cairo mailing list