From: Matthias Clasen Date: Sat, 31 Jul 2021 15:41:08 +0000 (-0400) Subject: gsk: Mark color glyphs X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~1^2~47^2~4 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=bb9dccd7735f3bcbccc53e5f75ac21f26bc11649;p=gtk4.git gsk: Mark color glyphs Steal a bit from PangoGlyphVisAttr to mark glyphs that have color. --- diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index 9a9705d0fd..9958b7e33c 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -4377,6 +4377,15 @@ gsk_text_node_draw (GskRenderNode *node, cairo_restore (cr); } +/* We steal one of the bits in PangoGlyphVisAttr */ + +G_STATIC_ASSERT (sizeof (PangoGlyphVisAttr) == 4); + +#define COLOR_GLYPH_BIT 2 +#define GLYPH_IS_COLOR(g) (((*(guint32*)&(g)->attr) & COLOR_GLYPH_BIT) != 0) +#define GLYPH_SET_COLOR(g) (*(guint32*)(&(g)->attr) |= COLOR_GLYPH_BIT) +#define GLYPH_CLEAR_COLOR(g) (*(guint32*)(&(g)->attr) &= ~COLOR_GLYPH_BIT) + static void gsk_text_node_diff (GskRenderNode *node1, GskRenderNode *node2, @@ -4401,7 +4410,8 @@ gsk_text_node_diff (GskRenderNode *node1, info1->geometry.width == info2->geometry.width && info1->geometry.x_offset == info2->geometry.x_offset && info1->geometry.y_offset == info2->geometry.y_offset && - info1->attr.is_cluster_start == info2->attr.is_cluster_start) + info1->attr.is_cluster_start == info2->attr.is_cluster_start && + GLYPH_IS_COLOR (info1) == GLYPH_IS_COLOR (info2)) continue; gsk_render_node_diff_impossible (node1, node2, region); @@ -4431,6 +4441,52 @@ font_has_color_glyphs (const PangoFont *font) return has_color; } +static gboolean +glyph_has_color (FT_Face face, + guint glyph) +{ + FT_Error error; + + error = FT_Load_Glyph (face, glyph, FT_LOAD_COLOR); + if (error != 0) + return FALSE; + + error = FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL); + if (error != 0) + return FALSE; + + if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) + return TRUE; + + return FALSE; +} + +static void +mark_color_glyphs (const PangoFont *font, + PangoGlyphInfo *glyphs, + int num_glyphs) +{ + cairo_scaled_font_t *scaled_font; + FT_Face ft_face; + + scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)font); + if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_FT) + return; + + ft_face = cairo_ft_scaled_font_lock_face (scaled_font); + if (!FT_HAS_COLOR (ft_face)) + goto out; + + for (int i = 0; i < num_glyphs; i++) + { + if (glyph_has_color (ft_face, glyphs[i].glyph)) + GLYPH_SET_COLOR (&glyphs[i]); + } + +out: + cairo_ft_scaled_font_unlock_face (scaled_font); +} + /** * gsk_text_node_new: * @font: the `PangoFont` containing the glyphs @@ -4476,9 +4532,15 @@ gsk_text_node_new (PangoFont *font, for (int i = 0; i < glyphs->num_glyphs; i++) { if (glyphs->glyphs[i].glyph != PANGO_GLYPH_EMPTY) - self->glyphs[self->num_glyphs++] = glyphs->glyphs[i]; + { + self->glyphs[self->num_glyphs] = glyphs->glyphs[i]; + GLYPH_CLEAR_COLOR (&self->glyphs[self->num_glyphs]); + self->num_glyphs++; + } } + mark_color_glyphs (font, self->glyphs, self->num_glyphs); + graphene_rect_init (&node->bounds, offset->x + ink_rect.x - 1, offset->y + ink_rect.y - 1,