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
This commit is contained in:
Ryan Hendrickson 2018-05-17 10:45:02 -04:00 committed by Florian Müllner
parent 5ac6201d91
commit f56ba0877a
5 changed files with 90 additions and 0 deletions

View File

@ -117,6 +117,7 @@ _st_set_text_from_style (ClutterText *text,
const PangoFontDescription *font; const PangoFontDescription *font;
StTextAlign align; StTextAlign align;
gdouble spacing; gdouble spacing;
gchar *font_features;
st_theme_node_get_foreground_color (theme_node, &color); st_theme_node_get_foreground_color (theme_node, &color);
clutter_text_set_color (text, &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); 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); clutter_text_set_attributes (text, attribs);
if (attribs) if (attribs)

View File

@ -3019,6 +3019,39 @@ st_theme_node_get_font (StThemeNode *node)
return node->font_desc; 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: * st_theme_node_get_border_image:
* @node: a #StThemeNode * @node: a #StThemeNode

View File

@ -232,6 +232,8 @@ double st_theme_node_get_letter_spacing (StThemeNode *node);
*/ */
const PangoFontDescription *st_theme_node_get_font (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); StBorderImage *st_theme_node_get_border_image (StThemeNode *node);
StShadow *st_theme_node_get_box_shadow (StThemeNode *node); StShadow *st_theme_node_get_box_shadow (StThemeNode *node);
StShadow *st_theme_node_get_text_shadow (StThemeNode *node); StShadow *st_theme_node_get_text_shadow (StThemeNode *node);

View File

@ -59,6 +59,24 @@ assert_font (StThemeNode *node,
g_free (value); 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 * static char *
text_decoration_to_string (StTextDecoration decoration) text_decoration_to_string (StTextDecoration decoration)
{ {
@ -413,6 +431,22 @@ test_font (void)
assert_font (text3, "text3", "serif Bold Oblique Small-Caps 24px"); 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 static void
test_pseudo_class (void) test_pseudo_class (void)
{ {
@ -554,6 +588,7 @@ main (int argc, char **argv)
test_border (); test_border ();
test_background (); test_background ();
test_font (); test_font ();
test_font_features ();
test_pseudo_class (); test_pseudo_class ();
test_inline_style (); test_inline_style ();

View File

@ -13,6 +13,8 @@ stage {
margin-left: 1in; margin-left: 1in;
background: #ff0000 url('some-background.png'); background: #ff0000 url('some-background.png');
font-feature-settings: "tnum";
} }
#text1 { #text1 {
@ -35,6 +37,7 @@ ClutterTexture.special-text {
#group2 { #group2 {
font: italic 12px serif; font: italic 12px serif;
font-feature-settings: "tnum", "zero";
} }
#text3 { #text3 {
@ -42,6 +45,11 @@ ClutterTexture.special-text {
font-weight: bold; font-weight: bold;
font-style: oblique; font-style: oblique;
font-size: 200%; font-size: 200%;
font-feature-settings: "pnum";
}
#text4 {
font-feature-settings: normal;
} }
ClutterTexture { ClutterTexture {
@ -60,6 +68,10 @@ stage > #text2 {
color: #ff0000; color: #ff0000;
} }
#group2 > #text3 {
font-feature-settings: inherit;
}
#group2 { #group2 {
background-image: url('other-background.png'); background-image: url('other-background.png');
padding: 1px 2px 3px 4px; padding: 1px 2px 3px 4px;