diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-09-01 05:42:43 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-09-01 05:42:43 +0000 |
commit | 44e5d0b2d435800516547be3c52af25190a918a5 (patch) | |
tree | 97c2a667f1b5e92b69de338e5915907c7692c70b | |
parent | 923284062075fd2fe1b061d256f91aec2912b1ab (diff) | |
parent | 7e329ab263eb75d7c4fb365d1a240656f34f32fd (diff) | |
download | pango-44e5d0b2d435800516547be3c52af25190a918a5.tar.gz |
Merge branch 'color-glyph' into 'main'
shape: Mark color glyphs in glyphstrings
See merge request GNOME/pango!466
-rw-r--r-- | pango/pango-glyph.h | 6 | ||||
-rw-r--r-- | pango/shape.c | 43 | ||||
-rw-r--r-- | tests/test-shape.c | 13 |
3 files changed, 58 insertions, 4 deletions
diff --git a/pango/pango-glyph.h b/pango/pango-glyph.h index cd29b77a..fae7168c 100644 --- a/pango/pango-glyph.h +++ b/pango/pango-glyph.h @@ -89,16 +89,18 @@ struct _PangoGlyphGeometry * are always ordered in logical order, since visual order is meaningless; * that is, in Arabic text, accent glyphs follow the glyphs for the * base character.) + * @is_color: set if the the font will render this glyph with color. Since 1.50 * * A `PangoGlyphVisAttr` structure communicates information between * the shaping and rendering phases. * - * Currently, it contains only cluster start information. More attributes - * may be added in the future. + * Currently, it contains cluster start and color information. + * More attributes may be added in the future. */ struct _PangoGlyphVisAttr { guint is_cluster_start : 1; + guint is_color : 1; }; /* A single glyph diff --git a/pango/shape.c b/pango/shape.c index 62c0f025..30131dd5 100644 --- a/pango/shape.c +++ b/pango/shape.c @@ -30,6 +30,8 @@ #include "pango-font-private.h" +#include <hb-ot.h> + /* {{{ Harfbuzz shaping */ /* {{{{ Buffer handling */ @@ -335,6 +337,45 @@ find_text_transform (const PangoAnalysis *analysis) return PANGO_TEXT_TRANSFORM_NONE; } +static gboolean +glyph_has_color (hb_font_t *font, + hb_codepoint_t glyph) +{ + hb_face_t *face; + hb_blob_t *blob; + + face = hb_font_get_face (font); + + if (hb_ot_color_glyph_get_layers (face, glyph, 0, NULL, NULL) > 0) + return TRUE; + + if (hb_ot_color_has_png (face)) + { + blob = hb_ot_color_glyph_reference_png (font, glyph); + if (blob) + { + guint length = hb_blob_get_length (blob); + hb_blob_destroy (blob); + if (length > 0) + return TRUE; + } + } + + if (hb_ot_color_has_svg (face)) + { + blob = hb_ot_color_glyph_reference_svg (face, glyph); + if (blob) + { + guint length = hb_blob_get_length (blob); + hb_blob_destroy (blob); + if (length > 0) + return TRUE; + } + } + + return FALSE; +} + /* }}}} */ static void @@ -495,11 +536,13 @@ pango_hb_shape (const char *item_text, pango_glyph_string_set_size (glyphs, num_glyphs); infos = glyphs->glyphs; last_cluster = -1; + for (i = 0; i < num_glyphs; i++) { infos[i].glyph = hb_glyph->codepoint; glyphs->log_clusters[i] = hb_glyph->cluster - item_offset; infos[i].attr.is_cluster_start = glyphs->log_clusters[i] != last_cluster; + infos[i].attr.is_color = glyph_has_color (hb_font, hb_glyph->codepoint); hb_glyph++; last_cluster = glyphs->log_clusters[i]; } diff --git a/tests/test-shape.c b/tests/test-shape.c index a16eb9d7..9380976f 100644 --- a/tests/test-shape.c +++ b/tests/test-shape.c @@ -142,7 +142,7 @@ test_file (const gchar *filename, GString *string) PangoAttrList *itemize_attrs; PangoAttrList *shape_attrs; GList *items, *l; - GString *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8; + GString *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9; char *p1; const char *sep = ""; @@ -174,6 +174,7 @@ test_file (const gchar *filename, GString *string) s6 = g_string_new ("Item: "); s7 = g_string_new ("Offset: "); s8 = g_string_new ("Class: "); + s9 = g_string_new ("Color: "); length = strlen (text); if (text[length - 1] == '\n') @@ -212,6 +213,7 @@ test_file (const gchar *filename, GString *string) g_string_append (s6, sep); g_string_append (s7, sep); g_string_append (s8, sep); + g_string_append (s9, sep); sep = "|"; g_string_append_printf (s6, "%d(%d)", item->num_chars, item->length); @@ -233,6 +235,7 @@ test_file (const gchar *filename, GString *string) g_string_append (s6, " "); g_string_append (s7, "|"); g_string_append (s8, "|"); + g_string_append (s9, "|"); } char *p; @@ -280,6 +283,8 @@ test_file (const gchar *filename, GString *string) default: g_assert_not_reached (); } + if (gi->attr.is_color) + g_string_append_printf (s9, "c"); len = 0; len = MAX (len, g_utf8_strlen (s1->str, s1->len)); len = MAX (len, g_utf8_strlen (s2->str, s2->len)); @@ -289,14 +294,16 @@ test_file (const gchar *filename, GString *string) len = MAX (len, g_utf8_strlen (s6->str, s6->len)); len = MAX (len, g_utf8_strlen (s7->str, s7->len)); len = MAX (len, g_utf8_strlen (s8->str, s8->len)); + len = MAX (len, g_utf8_strlen (s9->str, s9->len)); g_string_append_printf (s1, "%*s", len - (int)g_utf8_strlen (s1->str, s1->len), ""); - g_string_append_printf (s4, "%*s", len - (int)g_utf8_strlen (s4->str, s4->len), ""); g_string_append_printf (s2, "%*s", len - (int)g_utf8_strlen (s2->str, s2->len), ""); g_string_append_printf (s3, "%*s", len - (int)g_utf8_strlen (s3->str, s3->len), ""); + g_string_append_printf (s4, "%*s", len - (int)g_utf8_strlen (s4->str, s4->len), ""); g_string_append_printf (s5, "%*s", len - (int)g_utf8_strlen (s5->str, s5->len), ""); g_string_append_printf (s6, "%*s", len - (int)g_utf8_strlen (s6->str, s6->len), ""); g_string_append_printf (s7, "%*s", len - (int)g_utf8_strlen (s7->str, s7->len), ""); g_string_append_printf (s8, "%*s", len - (int)g_utf8_strlen (s8->str, s8->len), ""); + g_string_append_printf (s9, "%*s", len - (int)g_utf8_strlen (s9->str, s9->len), ""); } pango_glyph_string_free (glyphs); @@ -309,6 +316,7 @@ test_file (const gchar *filename, GString *string) g_string_append_printf (string, "%s\n", s3->str); g_string_append_printf (string, "%s\n", s2->str); g_string_append_printf (string, "%s\n", s8->str); + g_string_append_printf (string, "%s\n", s9->str); g_string_append_printf (string, "%s\n", s4->str); g_string_append_printf (string, "%s\n", s7->str); @@ -320,6 +328,7 @@ test_file (const gchar *filename, GString *string) g_string_free (s6, TRUE); g_string_free (s7, TRUE); g_string_free (s8, TRUE); + g_string_free (s9, TRUE); g_list_free_full (items, (GDestroyNotify)pango_item_free); g_free (contents); |