summaryrefslogtreecommitdiff
path: root/src/cairo-ft-font.c
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2021-08-27 23:12:24 +0930
committerAdrian Johnson <ajohnson@redneon.com>2021-08-28 18:07:01 +0930
commitfea24631076f74a3202ba0233be85588ae28db36 (patch)
tree1df67721f194ad6f161d5d63ddd146d05a0d0b68 /src/cairo-ft-font.c
parent5e76dd7a5c0585515eeef5099f12b273c94d3b0f (diff)
downloadcairo-fea24631076f74a3202ba0233be85588ae28db36.tar.gz
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.
Diffstat (limited to 'src/cairo-ft-font.c')
-rw-r--r--src/cairo-ft-font.c40
1 files changed, 38 insertions, 2 deletions
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))