From f56ba0877ab8fc60d8d63de51865856d88bdcac1 Mon Sep 17 00:00:00 2001 From: Ryan Hendrickson Date: Thu, 17 May 2018 10:45:02 -0400 Subject: [PATCH] st: Add support for font-feature-settings Cantarell now supports tabular figures, which are useful in places where digits should either align or not use different widths. In order to allow elements to request the feature, add support for the corresponding CSS property[0]. [0] https://www.w3.org/TR/css-fonts-3/#font-rend-desc https://gitlab.gnome.org/GNOME/gnome-shell/issues/34 --- src/st/st-private.c | 8 ++++++++ src/st/st-theme-node.c | 33 +++++++++++++++++++++++++++++++++ src/st/st-theme-node.h | 2 ++ src/st/test-theme.c | 35 +++++++++++++++++++++++++++++++++++ src/st/test-theme.css | 12 ++++++++++++ 5 files changed, 90 insertions(+) diff --git a/src/st/st-private.c b/src/st/st-private.c index a0100e094..882c2631e 100644 --- a/src/st/st-private.c +++ b/src/st/st-private.c @@ -117,6 +117,7 @@ _st_set_text_from_style (ClutterText *text, const PangoFontDescription *font; StTextAlign align; gdouble spacing; + gchar *font_features; st_theme_node_get_foreground_color (theme_node, &color); clutter_text_set_color (text, &color); @@ -151,6 +152,13 @@ _st_set_text_from_style (ClutterText *text, pango_attr_list_insert (attribs, letter_spacing); } + font_features = st_theme_node_get_font_features (theme_node); + if (font_features) + { + pango_attr_list_insert (attribs, pango_attr_font_features_new (font_features)); + g_free (font_features); + } + clutter_text_set_attributes (text, attribs); if (attribs) diff --git a/src/st/st-theme-node.c b/src/st/st-theme-node.c index fd2cdb084..69a0848af 100644 --- a/src/st/st-theme-node.c +++ b/src/st/st-theme-node.c @@ -3019,6 +3019,39 @@ st_theme_node_get_font (StThemeNode *node) return node->font_desc; } +gchar * +st_theme_node_get_font_features (StThemeNode *node) +{ + int i; + + ensure_properties (node); + + for (i = node->n_properties - 1; i >= 0; i--) + { + CRDeclaration *decl = node->properties[i]; + + if (strcmp (decl->property->stryng->str, "font-feature-settings") == 0) + { + CRTerm *term = decl->value; + + if (!term->next && term->type == TERM_IDENT) + { + gchar *ident = term->content.str->stryng->str; + + if (strcmp (ident, "inherit") == 0) + break; + + if (strcmp (ident, "normal") == 0) + return NULL; + } + + return (gchar *)cr_term_to_string (term); + } + } + + return node->parent_node ? st_theme_node_get_font_features (node->parent_node) : NULL; +} + /** * st_theme_node_get_border_image: * @node: a #StThemeNode diff --git a/src/st/st-theme-node.h b/src/st/st-theme-node.h index 08648e68a..e71c1d522 100644 --- a/src/st/st-theme-node.h +++ b/src/st/st-theme-node.h @@ -232,6 +232,8 @@ double st_theme_node_get_letter_spacing (StThemeNode *node); */ const PangoFontDescription *st_theme_node_get_font (StThemeNode *node); +gchar *st_theme_node_get_font_features (StThemeNode *node); + StBorderImage *st_theme_node_get_border_image (StThemeNode *node); StShadow *st_theme_node_get_box_shadow (StThemeNode *node); StShadow *st_theme_node_get_text_shadow (StThemeNode *node); diff --git a/src/st/test-theme.c b/src/st/test-theme.c index dfc26a5e9..225b95fc5 100644 --- a/src/st/test-theme.c +++ b/src/st/test-theme.c @@ -59,6 +59,24 @@ assert_font (StThemeNode *node, g_free (value); } +static void +assert_font_features (StThemeNode *node, + const char *node_description, + const char *expected) +{ + char *value = st_theme_node_get_font_features (node); + + if (g_strcmp0 (expected, value) != 0) + { + g_print ("%s: %s.font-feature-settings: expected: %s, got: %s\n", + test, node_description, expected, value); + fail = TRUE; + } + + if (value) + g_free (value); +} + static char * text_decoration_to_string (StTextDecoration decoration) { @@ -413,6 +431,22 @@ test_font (void) assert_font (text3, "text3", "serif Bold Oblique Small-Caps 24px"); } +static void +test_font_features (void) +{ + test = "font_features"; + /* group1 has font-feature-settings: "tnum" */ + assert_font_features (group1, "group1", "\"tnum\""); + /* text2 should inherit from group1 */ + assert_font_features (text2, "text2", "\"tnum\""); + /* group2 has font-feature-settings: "tnum", "zero" */ + assert_font_features (group2, "group2", "\"tnum\", \"zero\""); + /* text3 should inherit from group2 using the inherit keyword */ + assert_font_features (text3, "text3", "\"tnum\", \"zero\""); + /* text4 has font-feature-settings: normal */ + assert_font_features (text4, "text4", NULL); +} + static void test_pseudo_class (void) { @@ -554,6 +588,7 @@ main (int argc, char **argv) test_border (); test_background (); test_font (); + test_font_features (); test_pseudo_class (); test_inline_style (); diff --git a/src/st/test-theme.css b/src/st/test-theme.css index 0c0af1b06..d1816648d 100644 --- a/src/st/test-theme.css +++ b/src/st/test-theme.css @@ -13,6 +13,8 @@ stage { margin-left: 1in; background: #ff0000 url('some-background.png'); + + font-feature-settings: "tnum"; } #text1 { @@ -35,6 +37,7 @@ ClutterTexture.special-text { #group2 { font: italic 12px serif; + font-feature-settings: "tnum", "zero"; } #text3 { @@ -42,6 +45,11 @@ ClutterTexture.special-text { font-weight: bold; font-style: oblique; font-size: 200%; + font-feature-settings: "pnum"; +} + +#text4 { + font-feature-settings: normal; } ClutterTexture { @@ -60,6 +68,10 @@ stage > #text2 { color: #ff0000; } +#group2 > #text3 { + font-feature-settings: inherit; +} + #group2 { background-image: url('other-background.png'); padding: 1px 2px 3px 4px;