css: Implement font-variant-ligatures
This gets translated into corresponding OpenType features.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user