diff options
author | Matthias Clasen <mclasen@redhat.com> | 2017-09-17 23:52:04 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2017-09-18 14:26:57 -0400 |
commit | c4cbe5fecafcd2b244981769086081d4fbfb1fc2 (patch) | |
tree | 522a1d3b091b9d228175d2249a928d0c7dcb3d4b | |
parent | cee4622567f8eea0a2e168cbe641855cabd6e7ce (diff) | |
download | gtk+-c4cbe5fecafcd2b244981769086081d4fbfb1fc2.tar.gz |
css: Implement font-variant-ligatures
This gets translated into corresponding OpenType features.
-rw-r--r-- | gtk/gtkcssstyle.c | 38 | ||||
-rw-r--r-- | gtk/gtkcssstylepropertyimpl.c | 93 | ||||
-rw-r--r-- | gtk/gtkcsstypesprivate.h | 1 |
3 files changed, 130 insertions, 2 deletions
diff --git a/gtk/gtkcssstyle.c b/gtk/gtkcssstyle.c index dcce352b32..44a9f1c972 100644 --- a/gtk/gtkcssstyle.c +++ b/gtk/gtkcssstyle.c @@ -226,6 +226,9 @@ gtk_css_style_get_pango_attributes (GtkCssStyle *style) const GdkRGBA *decoration_color; gint letter_spacing; GtkCssValue *kerning; + GtkCssValue *ligatures; + GString *s; + int i; /* text-decoration */ decoration_line = _gtk_css_text_decoration_line_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_TEXT_DECORATION_LINE)); @@ -261,11 +264,42 @@ gtk_css_style_get_pango_attributes (GtkCssStyle *style) attrs = add_pango_attr (attrs, pango_attr_letter_spacing_new (letter_spacing * PANGO_SCALE)); } + /* OpenType features */ + s = g_string_new (""); + kerning = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_KERNING); if (strcmp (_gtk_css_ident_value_get (kerning), "normal") == 0) - attrs = add_pango_attr (attrs, pango_attr_font_features_new ("kern 1")); + g_string_append (s, "kern 1"); else if (strcmp (_gtk_css_ident_value_get (kerning), "none") == 0) - attrs = add_pango_attr (attrs, pango_attr_font_features_new ("kern 0")); + g_string_append (s, "kern 0"); + + ligatures = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_LIGATURES); + for (i = 0; i < _gtk_css_array_value_get_n_values (ligatures); i++) + { + GtkCssValue *value = _gtk_css_array_value_get_nth (ligatures, i); + if (s->len > 0) g_string_append (s, ", "); + if (strcmp (_gtk_css_ident_value_get (value), "none") == 0) + g_string_append (s, "liga 0, clig 0, dlig 0, hlig 0, calt 0"); + else if (strcmp (_gtk_css_ident_value_get (value), "common-ligatures") == 0) + g_string_append (s, "liga 1, clig 1"); + else if (strcmp (_gtk_css_ident_value_get (value), "no-common-ligatures") == 0) + g_string_append (s, "liga 0, clig 0"); + else if (strcmp (_gtk_css_ident_value_get (value), "discretionary-ligatures") == 0) + g_string_append (s, "dlig 1"); + else if (strcmp (_gtk_css_ident_value_get (value), "no-discretionary-ligatures") == 0) + g_string_append (s, "dlig 0"); + else if (strcmp (_gtk_css_ident_value_get (value), "historical-ligatures") == 0) + g_string_append (s, "hlig 1"); + else if (strcmp (_gtk_css_ident_value_get (value), "no-historical-ligatures") == 0) + g_string_append (s, "hlig 0"); + else if (strcmp (_gtk_css_ident_value_get (value), "contextual") == 0) + g_string_append (s, "calt 1"); + else if (strcmp (_gtk_css_ident_value_get (value), "no-contextual") == 0) + g_string_append (s, "calt 0"); + } + + attrs = add_pango_attr (attrs, pango_attr_font_features_new (s->str)); + g_string_free (s, TRUE); return attrs; } diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c index bf98160fd1..a07fe1b527 100644 --- a/gtk/gtkcssstylepropertyimpl.c +++ b/gtk/gtkcssstylepropertyimpl.c @@ -543,6 +543,91 @@ parse_font_kerning (GtkCssStyleProperty *property, return value; } +static gboolean +value_is_done_parsing (GtkCssParser *parser) +{ + return _gtk_css_parser_is_eof (parser) || + _gtk_css_parser_begins_with (parser, ',') || + _gtk_css_parser_begins_with (parser, ';') || + _gtk_css_parser_begins_with (parser, '}'); +} + +static GtkCssValue * +parse_font_variant_ligatures (GtkCssStyleProperty *property, + GtkCssParser *parser) +{ + GtkCssValue *value = NULL; + + if (_gtk_css_parser_try (parser, "normal", TRUE)) + value = _gtk_css_array_value_new (_gtk_css_ident_value_new ("normal")); + else if (_gtk_css_parser_try (parser, "none", TRUE)) + value = _gtk_css_array_value_new (_gtk_css_ident_value_new ("none")); + else + { + GtkCssValue *values[4] = { NULL, NULL, NULL, NULL }; + guint n_values = 0; + guint old_n; + gboolean common = FALSE; + gboolean discretionary = FALSE; + gboolean historical = FALSE; + gboolean contextual = FALSE; + + do { + old_n = n_values; + if (!common) + { + values[n_values] = _gtk_css_ident_value_try (parser, "common-ligatures", + "no-common-ligatures", NULL); + if (values[n_values]) + { + n_values++; + common = TRUE; + } + } + if (!discretionary) + { + values[n_values] = _gtk_css_ident_value_try (parser, "discretionary-ligatures", + "no-discretionary-ligatures", NULL); + if (values[n_values]) + { + n_values++; + discretionary = TRUE; + } + } + if (!historical) + { + values[n_values] = _gtk_css_ident_value_try (parser, "historical-ligatures", + "no-historical-ligatures", + NULL); + if (values[n_values]) + { + n_values++; + historical = TRUE; + } + } + if (!contextual) + { + values[n_values] = _gtk_css_ident_value_try (parser, "contextual", + "no-contextual", NULL); + if (values[n_values]) + { + n_values++; + contextual = TRUE; + } + } + if (old_n == n_values) + { + _gtk_css_parser_error (parser, "Not a valid value"); + return NULL; + } + } while (!value_is_done_parsing (parser)); + + value = _gtk_css_array_value_new_from_array (values, n_values); + } + + return value; +} + static GtkCssValue * box_shadow_value_parse (GtkCssStyleProperty *property, GtkCssParser *parser) @@ -1036,6 +1121,14 @@ _gtk_css_style_property_init_properties (void) parse_font_kerning, NULL, _gtk_css_ident_value_new ("auto")); + gtk_css_style_property_register ("font-variant-ligatures", + GTK_CSS_PROPERTY_FONT_VARIANT_LIGATURES, + G_TYPE_NONE, + 0, + GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS, + parse_font_variant_ligatures, + NULL, + _gtk_css_array_value_new (_gtk_css_ident_value_new ("normal"))); gtk_css_style_property_register ("text-shadow", GTK_CSS_PROPERTY_TEXT_SHADOW, diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h index b4f79fb80c..2ff67500c3 100644 --- a/gtk/gtkcsstypesprivate.h +++ b/gtk/gtkcsstypesprivate.h @@ -164,6 +164,7 @@ enum { /*< skip >*/ GTK_CSS_PROPERTY_TEXT_DECORATION_COLOR, GTK_CSS_PROPERTY_TEXT_DECORATION_STYLE, GTK_CSS_PROPERTY_FONT_KERNING, + GTK_CSS_PROPERTY_FONT_VARIANT_LIGATURES, GTK_CSS_PROPERTY_TEXT_SHADOW, GTK_CSS_PROPERTY_BOX_SHADOW, GTK_CSS_PROPERTY_MARGIN_TOP, |