summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2017-09-17 23:52:04 -0400
committerMatthias Clasen <mclasen@redhat.com>2017-09-18 14:26:57 -0400
commitc4cbe5fecafcd2b244981769086081d4fbfb1fc2 (patch)
tree522a1d3b091b9d228175d2249a928d0c7dcb3d4b /gtk
parentcee4622567f8eea0a2e168cbe641855cabd6e7ce (diff)
downloadgtk+-c4cbe5fecafcd2b244981769086081d4fbfb1fc2.tar.gz
css: Implement font-variant-ligatures
This gets translated into corresponding OpenType features.
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtkcssstyle.c38
-rw-r--r--gtk/gtkcssstylepropertyimpl.c93
-rw-r--r--gtk/gtkcsstypesprivate.h1
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,