diff options
author | Matthias Clasen <mclasen@redhat.com> | 2017-09-18 18:38:16 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2017-09-18 23:22:38 -0400 |
commit | 6859f0a6d13ccb3bbe78e34dade0c588a2d6ed2a (patch) | |
tree | 15b205a5b71ebce59b4665a19331bef50a6e1e34 /gtk | |
parent | 01911b5ecd96e726335a7a18e27030a2304671b0 (diff) | |
download | gtk+-6859f0a6d13ccb3bbe78e34dade0c588a2d6ed2a.tar.gz |
css: Use enums instead of idents for font-variant properties
As Benjamin says, ident should only be used if any value
is valid, which is not the case here. So use enums instead,
which should also be more efficient. To handle the more
complicated cases like font-variant-ligatures, we have to
introduce flags-like values.
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtkcssenumvalue.c | 567 | ||||
-rw-r--r-- | gtk/gtkcssenumvalueprivate.h | 32 | ||||
-rw-r--r-- | gtk/gtkcssshorthandpropertyimpl.c | 257 | ||||
-rw-r--r-- | gtk/gtkcssstyle.c | 241 | ||||
-rw-r--r-- | gtk/gtkcssstylepropertyimpl.c | 271 | ||||
-rw-r--r-- | gtk/gtkcsstypesprivate.h | 65 |
6 files changed, 958 insertions, 475 deletions
diff --git a/gtk/gtkcssenumvalue.c b/gtk/gtkcssenumvalue.c index b4b31daa74..f5a0aa0266 100644 --- a/gtk/gtkcssenumvalue.c +++ b/gtk/gtkcssenumvalue.c @@ -936,3 +936,570 @@ _gtk_css_icon_style_value_get (const GtkCssValue *value) return value->value; } + +/* GtkCssFontKerning */ + +static const GtkCssValueClass GTK_CSS_VALUE_FONT_KERNING = { + gtk_css_value_enum_free, + gtk_css_value_enum_compute, + gtk_css_value_enum_equal, + gtk_css_value_enum_transition, + gtk_css_value_enum_print +}; + +static GtkCssValue font_kerning_values[] = { + { >K_CSS_VALUE_FONT_KERNING, 1, GTK_CSS_FONT_KERNING_AUTO, "auto" }, + { >K_CSS_VALUE_FONT_KERNING, 1, GTK_CSS_FONT_KERNING_NORMAL, "normal" }, + { >K_CSS_VALUE_FONT_KERNING, 1, GTK_CSS_FONT_KERNING_NONE, "none" } +}; + +GtkCssValue * +_gtk_css_font_kerning_value_new (GtkCssFontKerning kerning) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (font_kerning_values); i++) + { + if (font_kerning_values[i].value == kerning) + return _gtk_css_value_ref (&font_kerning_values[i]); + } + + g_return_val_if_reached (NULL); +} + +GtkCssValue * +_gtk_css_font_kerning_value_try_parse (GtkCssParser *parser) +{ + guint i; + + g_return_val_if_fail (parser != NULL, NULL); + + for (i = 0; i < G_N_ELEMENTS (font_kerning_values); i++) + { + if (_gtk_css_parser_try (parser, font_kerning_values[i].name, TRUE)) + return _gtk_css_value_ref (&font_kerning_values[i]); + } + + return NULL; +} + +GtkCssFontKerning +_gtk_css_font_kerning_value_get (const GtkCssValue *value) +{ + g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_KERNING, GTK_CSS_FONT_KERNING_AUTO); + + return value->value; +} + +/* GtkCssFontVariantPos */ + +static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_POSITION = { + gtk_css_value_enum_free, + gtk_css_value_enum_compute, + gtk_css_value_enum_equal, + gtk_css_value_enum_transition, + gtk_css_value_enum_print +}; + +static GtkCssValue font_variant_position_values[] = { + { >K_CSS_VALUE_FONT_VARIANT_POSITION, 1, GTK_CSS_FONT_VARIANT_POSITION_NORMAL, "normal" }, + { >K_CSS_VALUE_FONT_VARIANT_POSITION, 1, GTK_CSS_FONT_VARIANT_POSITION_SUB, "sub" }, + { >K_CSS_VALUE_FONT_VARIANT_POSITION, 1, GTK_CSS_FONT_VARIANT_POSITION_SUPER, "super" } +}; + +GtkCssValue * +_gtk_css_font_variant_position_value_new (GtkCssFontVariantPosition position) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (font_variant_position_values); i++) + { + if (font_variant_position_values[i].value == position) + return _gtk_css_value_ref (&font_variant_position_values[i]); + } + + g_return_val_if_reached (NULL); +} + +GtkCssValue * +_gtk_css_font_variant_position_value_try_parse (GtkCssParser *parser) +{ + guint i; + + g_return_val_if_fail (parser != NULL, NULL); + + for (i = 0; i < G_N_ELEMENTS (font_variant_position_values); i++) + { + if (_gtk_css_parser_try (parser, font_variant_position_values[i].name, TRUE)) + return _gtk_css_value_ref (&font_variant_position_values[i]); + } + + return NULL; +} + +GtkCssFontVariantPosition +_gtk_css_font_variant_position_value_get (const GtkCssValue *value) +{ + g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_POSITION, GTK_CSS_FONT_VARIANT_POSITION_NORMAL); + + return value->value; +} + +/* GtkCssFontVariantCaps */ + +static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_CAPS = { + gtk_css_value_enum_free, + gtk_css_value_enum_compute, + gtk_css_value_enum_equal, + gtk_css_value_enum_transition, + gtk_css_value_enum_print +}; + +static GtkCssValue font_variant_caps_values[] = { + { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_NORMAL, "normal" }, + { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_SMALL_CAPS, "small-caps" }, + { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_ALL_SMALL_CAPS, "all-small-caps" }, + { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_PETITE_CAPS, "petite-caps" }, + { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_ALL_PETITE_CAPS, "all-petite-caps" }, + { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_UNICASE, "unicase" }, + { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_TITLING_CAPS, "titling-caps" } +}; + +GtkCssValue * +_gtk_css_font_variant_caps_value_new (GtkCssFontVariantCaps caps) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (font_variant_caps_values); i++) + { + if (font_variant_caps_values[i].value == caps) + return _gtk_css_value_ref (&font_variant_caps_values[i]); + } + + g_return_val_if_reached (NULL); +} + +GtkCssValue * +_gtk_css_font_variant_caps_value_try_parse (GtkCssParser *parser) +{ + guint i; + + g_return_val_if_fail (parser != NULL, NULL); + + for (i = 0; i < G_N_ELEMENTS (font_variant_caps_values); i++) + { + if (_gtk_css_parser_try (parser, font_variant_caps_values[i].name, TRUE)) + return _gtk_css_value_ref (&font_variant_caps_values[i]); + } + + return NULL; +} + +GtkCssFontVariantCaps +_gtk_css_font_variant_caps_value_get (const GtkCssValue *value) +{ + g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_CAPS, GTK_CSS_FONT_VARIANT_CAPS_NORMAL); + + return value->value; +} + +/* GtkCssFontVariantAlternate */ + +static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_ALTERNATE = { + gtk_css_value_enum_free, + gtk_css_value_enum_compute, + gtk_css_value_enum_equal, + gtk_css_value_enum_transition, + gtk_css_value_enum_print +}; + +static GtkCssValue font_variant_alternate_values[] = { + { >K_CSS_VALUE_FONT_VARIANT_ALTERNATE, 1, GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL, "normal" }, + { >K_CSS_VALUE_FONT_VARIANT_ALTERNATE, 1, GTK_CSS_FONT_VARIANT_ALTERNATE_HISTORICAL_FORMS, "historical-forms" } +}; + +GtkCssValue * +_gtk_css_font_variant_alternate_value_new (GtkCssFontVariantAlternate alternate) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (font_variant_alternate_values); i++) + { + if (font_variant_alternate_values[i].value == alternate) + return _gtk_css_value_ref (&font_variant_alternate_values[i]); + } + + g_return_val_if_reached (NULL); +} + +GtkCssValue * +_gtk_css_font_variant_alternate_value_try_parse (GtkCssParser *parser) +{ + guint i; + + g_return_val_if_fail (parser != NULL, NULL); + + for (i = 0; i < G_N_ELEMENTS (font_variant_alternate_values); i++) + { + if (_gtk_css_parser_try (parser, font_variant_alternate_values[i].name, TRUE)) + return _gtk_css_value_ref (&font_variant_alternate_values[i]); + } + + return NULL; +} + +GtkCssFontVariantAlternate +_gtk_css_font_variant_alternate_value_get (const GtkCssValue *value) +{ + g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_ALTERNATE, GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL); + + return value->value; +} + +/* below are flags, which are handle a bit differently. We allocate values dynamically, + * and we parse one bit at a time, while allowing for detection of invalid combinations. + */ + +typedef struct { + int value; + const char *name; +} FlagsValue; + +static gboolean +gtk_css_value_flags_equal (const GtkCssValue *enum1, + const GtkCssValue *enum2) +{ + return enum1->value == enum2->value; +} + +static void +gtk_css_value_flags_print (const FlagsValue *values, + guint n_values, + const GtkCssValue *value, + GString *string) +{ + guint i; + const char *sep = ""; + + for (i = 0; i < n_values; i++) + { + if (value->value & values[i].value) + { + g_string_append (string, sep); + g_string_append (string, values[i].name); + sep = " "; + } + } +} + +/* GtkCssFontVariantLigature */ + +static FlagsValue font_variant_ligature_values[] = { + { GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL, "normal" }, + { GTK_CSS_FONT_VARIANT_LIGATURE_NONE, "none" }, + { GTK_CSS_FONT_VARIANT_LIGATURE_COMMON_LIGATURES, "common-ligatures" }, + { GTK_CSS_FONT_VARIANT_LIGATURE_NO_COMMON_LIGATURES, "no-common-ligatures" }, + { GTK_CSS_FONT_VARIANT_LIGATURE_DISCRETIONARY_LIGATURES, "discretionary-ligatures" }, + { GTK_CSS_FONT_VARIANT_LIGATURE_NO_DISCRETIONARY_LIGATURES, "no-discretionary-ligatures" }, + { GTK_CSS_FONT_VARIANT_LIGATURE_HISTORICAL_LIGATURES, "historical-ligatures" }, + { GTK_CSS_FONT_VARIANT_LIGATURE_NO_HISTORICAL_LIGATURES, "no-historical-ligatures" }, + { GTK_CSS_FONT_VARIANT_LIGATURE_CONTEXTUAL, "contextual" }, + { GTK_CSS_FONT_VARIANT_LIGATURE_NO_CONTEXTUAL, "no-contextual" } +}; + +static void +gtk_css_font_variant_ligature_value_print (const GtkCssValue *value, + GString *string) +{ + gtk_css_value_flags_print (font_variant_ligature_values, + G_N_ELEMENTS (font_variant_ligature_values), + value, string); +} + +static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_LIGATURE = { + gtk_css_value_enum_free, + gtk_css_value_enum_compute, + gtk_css_value_flags_equal, + gtk_css_value_enum_transition, + gtk_css_font_variant_ligature_value_print +}; + +static gboolean +ligature_value_is_valid (GtkCssFontVariantLigature ligatures) +{ + if (((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL) && + (ligatures != GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL)) || + ((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NONE) && + (ligatures != GTK_CSS_FONT_VARIANT_LIGATURE_NONE)) || + ((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_COMMON_LIGATURES) && + (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_COMMON_LIGATURES)) || + ((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_DISCRETIONARY_LIGATURES) && + (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_DISCRETIONARY_LIGATURES)) || + ((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_HISTORICAL_LIGATURES) && + (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_HISTORICAL_LIGATURES)) || + ((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_CONTEXTUAL) && + (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_CONTEXTUAL))) + return FALSE; + + return TRUE; +} + +GtkCssValue * +_gtk_css_font_variant_ligature_value_new (GtkCssFontVariantLigature ligatures) +{ + GtkCssValue *value; + + if (!ligature_value_is_valid (ligatures)) + return NULL; + + value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_FONT_VARIANT_LIGATURE); + value->value = ligatures; + value->name = NULL; + + return value; +} + +GtkCssFontVariantLigature +_gtk_css_font_variant_ligature_try_parse_one (GtkCssParser *parser, + GtkCssFontVariantLigature base) +{ + guint i; + GtkCssFontVariantLigature value = 0; + + g_return_val_if_fail (parser != NULL, 0); + + for (i = 0; i < G_N_ELEMENTS (font_variant_ligature_values); i++) + { + if (_gtk_css_parser_try (parser, font_variant_ligature_values[i].name, TRUE)) + { + value = font_variant_ligature_values[i].value; + break; + } + } + + if (value == 0) + return base; /* not parsing this value */ + + if ((base | value) == base) + return 0; /* repeated value */ + + if (!ligature_value_is_valid (base | value)) + return 0; /* bad combination */ + + return base | value; +} + +GtkCssFontVariantLigature +_gtk_css_font_variant_ligature_value_get (const GtkCssValue *value) +{ + g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_LIGATURE, GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL); + + return value->value; +} + +/* GtkCssFontVariantNumeric */ + +static FlagsValue font_variant_numeric_values[] = { + { GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL, "normal" }, + { GTK_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS, "lining-nums" }, + { GTK_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS, "oldstyle-nums" }, + { GTK_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS, "proportional-nums" }, + { GTK_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS, "tabular-nums" }, + { GTK_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS, "diagonal-fractions" }, + { GTK_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS, "stacked-fractions" }, + { GTK_CSS_FONT_VARIANT_NUMERIC_ORDINAL, "ordinal" }, + { GTK_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO, "slashed-zero" } +}; + +static void +gtk_css_font_variant_numeric_value_print (const GtkCssValue *value, + GString *string) +{ + gtk_css_value_flags_print (font_variant_numeric_values, + G_N_ELEMENTS (font_variant_numeric_values), + value, string); +} + +static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_NUMERIC = { + gtk_css_value_enum_free, + gtk_css_value_enum_compute, + gtk_css_value_flags_equal, + gtk_css_value_enum_transition, + gtk_css_font_variant_numeric_value_print +}; + +static gboolean +numeric_value_is_valid (GtkCssFontVariantNumeric numeric) +{ + if (((numeric & GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL) && + (numeric != GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL)) || + ((numeric & GTK_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS) && + (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS)) || + ((numeric & GTK_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS) && + (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS)) || + ((numeric & GTK_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS) && + (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS))) + return FALSE; + + return TRUE; +} + +GtkCssValue * +_gtk_css_font_variant_numeric_value_new (GtkCssFontVariantNumeric numeric) +{ + GtkCssValue *value; + + if (!numeric_value_is_valid (numeric)) + return NULL; + + value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_FONT_VARIANT_NUMERIC); + value->value = numeric; + value->name = NULL; + + return value; +} + +GtkCssFontVariantNumeric +_gtk_css_font_variant_numeric_try_parse_one (GtkCssParser *parser, + GtkCssFontVariantNumeric base) +{ + guint i; + GtkCssFontVariantNumeric value = 0; + + g_return_val_if_fail (parser != NULL, 0); + + for (i = 0; i < G_N_ELEMENTS (font_variant_numeric_values); i++) + { + if (_gtk_css_parser_try (parser, font_variant_numeric_values[i].name, TRUE)) + { + value = font_variant_numeric_values[i].value; + break; + } + } + + if (value == 0) + return base; /* not parsing this value */ + + if ((base | value) == base) + return 0; /* repeated value */ + + if (!numeric_value_is_valid (base | value)) + return 0; /* bad combination */ + + return base | value; +} + +GtkCssFontVariantNumeric +_gtk_css_font_variant_numeric_value_get (const GtkCssValue *value) +{ + g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_NUMERIC, GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL); + + return value->value; +} + +/* GtkCssFontVariantEastAsian */ + +static FlagsValue font_variant_east_asian_values[] = { + { GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL, "normal" }, + { GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS78, "jis78" }, + { GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS83, "jis83" }, + { GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS90, "jis90" }, + { GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS04, "jis04" }, + { GTK_CSS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED, "simplified" }, + { GTK_CSS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL, "traditional" }, + { GTK_CSS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH, "full-width" }, + { GTK_CSS_FONT_VARIANT_EAST_ASIAN_PROPORTIONAL, "proportional-width" }, + { GTK_CSS_FONT_VARIANT_EAST_ASIAN_RUBY, "ruby" } +}; + +static void +gtk_css_font_variant_east_asian_value_print (const GtkCssValue *value, + GString *string) +{ + gtk_css_value_flags_print (font_variant_east_asian_values, + G_N_ELEMENTS (font_variant_east_asian_values), + value, string); +} + +static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_EAST_ASIAN = { + gtk_css_value_enum_free, + gtk_css_value_enum_compute, + gtk_css_value_flags_equal, + gtk_css_value_enum_transition, + gtk_css_font_variant_east_asian_value_print +}; + +static gboolean +east_asian_value_is_valid (GtkCssFontVariantEastAsian east_asian) +{ + if ((east_asian & GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL) && + (east_asian != GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL)) + return FALSE; + + if (__builtin_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS78 | + GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS83 | + GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS90 | + GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS04 | + GTK_CSS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED | + GTK_CSS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL)) > 1) + return FALSE; + + if (__builtin_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH | + GTK_CSS_FONT_VARIANT_EAST_ASIAN_PROPORTIONAL)) > 1) + return FALSE; + + return TRUE; +} + +GtkCssValue * +_gtk_css_font_variant_east_asian_value_new (GtkCssFontVariantEastAsian east_asian) +{ + GtkCssValue *value; + + if (!east_asian_value_is_valid (east_asian)) + return NULL; + + value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_FONT_VARIANT_EAST_ASIAN); + value->value = east_asian; + value->name = NULL; + + return value; +} + +GtkCssFontVariantEastAsian +_gtk_css_font_variant_east_asian_try_parse_one (GtkCssParser *parser, + GtkCssFontVariantEastAsian base) +{ + guint i; + GtkCssFontVariantEastAsian value = 0; + + g_return_val_if_fail (parser != NULL, 0); + + for (i = 0; i < G_N_ELEMENTS (font_variant_east_asian_values); i++) + { + if (_gtk_css_parser_try (parser, font_variant_east_asian_values[i].name, TRUE)) + { + value = font_variant_east_asian_values[i].value; + break; + } + } + + if (value == 0) + return base; /* not parsing this value */ + + if ((base | value) == base) + return 0; /* repeated value */ + + if (!east_asian_value_is_valid (base | value)) + return 0; /* bad combination */ + + return base | value; +} + +GtkCssFontVariantEastAsian +_gtk_css_font_variant_east_asian_value_get (const GtkCssValue *value) +{ + g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_EAST_ASIAN, GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL); + + return value->value; +} diff --git a/gtk/gtkcssenumvalueprivate.h b/gtk/gtkcssenumvalueprivate.h index bdb4d2aebb..753ec895f1 100644 --- a/gtk/gtkcssenumvalueprivate.h +++ b/gtk/gtkcssenumvalueprivate.h @@ -81,6 +81,38 @@ GtkCssValue * _gtk_css_icon_style_value_new (GtkCssIconStyle icon_s GtkCssValue * _gtk_css_icon_style_value_try_parse (GtkCssParser *parser); GtkCssIconStyle _gtk_css_icon_style_value_get (const GtkCssValue *value); +GtkCssValue * _gtk_css_font_kerning_value_new (GtkCssFontKerning kerning); +GtkCssValue * _gtk_css_font_kerning_value_try_parse (GtkCssParser *parser); +GtkCssFontKerning _gtk_css_font_kerning_value_get (const GtkCssValue *value); + +GtkCssValue * _gtk_css_font_variant_position_value_new (GtkCssFontVariantPosition position); +GtkCssValue * _gtk_css_font_variant_position_value_try_parse (GtkCssParser *parser); +GtkCssFontVariantPosition _gtk_css_font_variant_position_value_get (const GtkCssValue *value); + +GtkCssValue * _gtk_css_font_variant_caps_value_new (GtkCssFontVariantCaps caps); +GtkCssValue * _gtk_css_font_variant_caps_value_try_parse (GtkCssParser *parser); +GtkCssFontVariantCaps _gtk_css_font_variant_caps_value_get (const GtkCssValue *value); + +GtkCssValue * _gtk_css_font_variant_alternate_value_new (GtkCssFontVariantAlternate alternates); +GtkCssValue * _gtk_css_font_variant_alternate_value_try_parse (GtkCssParser *parser); +GtkCssFontVariantAlternate _gtk_css_font_variant_alternate_value_get (const GtkCssValue *value); + +GtkCssValue * _gtk_css_font_variant_ligature_value_new (GtkCssFontVariantLigature ligatures); +GtkCssFontVariantLigature _gtk_css_font_variant_ligature_try_parse_one (GtkCssParser *parser, + GtkCssFontVariantLigature base); +GtkCssFontVariantLigature _gtk_css_font_variant_ligature_value_get (const GtkCssValue *value); + +GtkCssValue * _gtk_css_font_variant_numeric_value_new (GtkCssFontVariantNumeric numeric); +GtkCssFontVariantNumeric _gtk_css_font_variant_numeric_try_parse_one (GtkCssParser *parser, + GtkCssFontVariantNumeric base); +GtkCssFontVariantNumeric _gtk_css_font_variant_numeric_value_get (const GtkCssValue *value); + + +GtkCssValue * _gtk_css_font_variant_east_asian_value_new (GtkCssFontVariantEastAsian east_asian); +GtkCssFontVariantEastAsian _gtk_css_font_variant_east_asian_try_parse_one (GtkCssParser *parser, + GtkCssFontVariantEastAsian base); +GtkCssFontVariantEastAsian _gtk_css_font_variant_east_asian_value_get (const GtkCssValue *value); + G_END_DECLS #endif /* __GTK_CSS_ENUM_VALUE_PRIVATE_H__ */ diff --git a/gtk/gtkcssshorthandpropertyimpl.c b/gtk/gtkcssshorthandpropertyimpl.c index 40b96c6a1d..751e6c28f8 100644 --- a/gtk/gtkcssshorthandpropertyimpl.c +++ b/gtk/gtkcssshorthandpropertyimpl.c @@ -878,202 +878,153 @@ parse_font_variant (GtkCssShorthandProperty *shorthand, else if (_gtk_css_parser_try (parser, "none", TRUE)) { /* all initial values, except for font-variant-ligatures */ - values[0] = _gtk_css_array_value_new (_gtk_css_ident_value_new ("none")); + values[0] = _gtk_css_font_variant_ligature_value_new (GTK_CSS_FONT_VARIANT_LIGATURE_NONE); } else { - gboolean found; - GtkCssValue *lig_values[4] = { NULL, NULL, NULL, NULL }; - guint n_ligs = 0; - gboolean common = FALSE; - gboolean discretionary = FALSE; - gboolean historical = FALSE; - gboolean contextual = FALSE; - GtkCssValue *num_values[5] = { NULL, NULL, NULL, NULL }; - guint n_num = 0; - gboolean figure = FALSE; - gboolean spacing = FALSE; - gboolean fraction = FALSE; - gboolean ordinal = FALSE; - gboolean zero = FALSE; - GtkCssValue *alt_value; - GtkCssValue *ea_values[5] = { NULL, NULL, NULL, NULL }; - guint n_ea = 0; - gboolean variant = FALSE; - gboolean width = FALSE; - gboolean ruby = FALSE; + GtkCssFontVariantLigature ligatures; + GtkCssFontVariantNumeric numeric; + GtkCssFontVariantEastAsian east_asian; + ligatures = 0; + numeric = 0; + east_asian = 0; do { - found = FALSE; - if (!common) - { - lig_values[n_ligs] = _gtk_css_ident_value_try (parser, "common-ligatures", - "no-common-ligatures", NULL); - if (lig_values[n_ligs]) - { - n_ligs++; - common = TRUE; - found = TRUE; - } - } - if (!discretionary) + GtkCssFontVariantLigature parsed_ligature; + GtkCssFontVariantNumeric parsed_numeric; + GtkCssFontVariantEastAsian parsed_east_asian; + + parsed_ligature = _gtk_css_font_variant_ligature_try_parse_one (parser, ligatures); + if (parsed_ligature == 0 && ligatures != 0) { - lig_values[n_ligs] = _gtk_css_ident_value_try (parser, "discretionary-ligatures", - "no-discretionary-ligatures", NULL); - if (lig_values[n_ligs]) - { - n_ligs++; - discretionary = TRUE; - found = TRUE; - } + _gtk_css_parser_error (parser, "Invalid combination of ligature values"); + return FALSE; } - if (!historical) + if (parsed_ligature == GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL || + parsed_ligature == GTK_CSS_FONT_VARIANT_LIGATURE_NONE) { - lig_values[n_ligs] = _gtk_css_ident_value_try (parser, "historical-ligatures", - "no-historical-ligatures", NULL); - if (lig_values[n_ligs]) - { - n_ligs++; - historical = TRUE; - found = TRUE; - } + _gtk_css_parser_error (parser, "Unexpected ligature value"); + return FALSE; } - if (!contextual) + if (parsed_ligature != ligatures) { - lig_values[n_ligs] = _gtk_css_ident_value_try (parser, "contextual", - "no-contextual", NULL); - if (lig_values[n_ligs]) - { - n_ligs++; - contextual = TRUE; - found = TRUE; - } + ligatures = parsed_ligature; + goto found; } - if (!figure) + parsed_numeric = _gtk_css_font_variant_numeric_try_parse_one (parser, numeric); + if (parsed_numeric == 0 && numeric != 0) { - num_values[n_num] = _gtk_css_ident_value_try (parser, "lining-nums", - "oldstyle-nums", NULL); - if (num_values[n_num]) - { - n_num++; - figure = TRUE; - found = TRUE; - } + _gtk_css_parser_error (parser, "Invalid combination of numeric values"); + return FALSE; } - if (!spacing) + if (parsed_numeric == GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL) { - num_values[n_num] = _gtk_css_ident_value_try (parser, "proportional-nums", - "tabular-nums", NULL); - if (num_values[n_num]) - { - n_num++; - spacing = TRUE; - found = TRUE; - } + _gtk_css_parser_error (parser, "Unexpected numeric value"); + return FALSE; } - if (!fraction) + if (parsed_numeric != numeric) { - num_values[n_num] = _gtk_css_ident_value_try (parser, "diagonal-fractions", - "stacked-fractions", NULL); - if (num_values[n_num]) - { - n_num++; - fraction = TRUE; - found = TRUE; - } + numeric = parsed_numeric; + goto found; } - if (!ordinal) + + parsed_east_asian = _gtk_css_font_variant_east_asian_try_parse_one (parser, east_asian); + if (parsed_east_asian == 0 && east_asian != 0) { - num_values[n_num] = _gtk_css_ident_value_try (parser, "ordinal", NULL); - if (num_values[n_num]) - { - n_num++; - ordinal = TRUE; - found = TRUE; - } + _gtk_css_parser_error (parser, "Invalid combination of east asian values"); + return FALSE; } - if (!zero) + if (parsed_east_asian == GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL) { - num_values[n_num] = _gtk_css_ident_value_try (parser, "slashed-zero", NULL); - if (num_values[n_num]) - { - n_num++; - zero = TRUE; - found = TRUE; - } + _gtk_css_parser_error (parser, "Unexpected east asian value"); + return FALSE; } - if (alt_value == NULL) + if (parsed_east_asian != east_asian) { - alt_value = _gtk_css_ident_value_try (parser, "historical-forms", NULL); - if (alt_value) - found = TRUE; + east_asian = parsed_east_asian; + goto found; } if (values[1] == NULL) { - values[1] = _gtk_css_ident_value_try (parser, "sub", "super", NULL); + values[1] = _gtk_css_font_variant_position_value_try_parse (parser); if (values[1]) - found = TRUE; + { + if (_gtk_css_font_variant_position_value_get (values[1]) == GTK_CSS_FONT_VARIANT_POSITION_NORMAL) + { + _gtk_css_parser_error (parser, "Unexpected position value"); + return FALSE; + } + goto found; + } } if (values[2] == NULL) { - values[2] = _gtk_css_ident_value_try (parser, "small-caps", "all-small-caps", - "petite-caps", "all-petite-caps", - "unicase", "titling-caps", NULL); + values[2] = _gtk_css_font_variant_caps_value_try_parse (parser); if (values[2]) - found = TRUE; - } - - if (!variant) - { - ea_values[n_ea] = _gtk_css_ident_value_try (parser, "jis78", "jis83", "jis90", "jis04", - "simplified", "traditional", NULL); - if (ea_values[n_ea]) - { - n_ea++; - variant = TRUE; - } - } - if (!width) - { - ea_values[n_ea] = _gtk_css_ident_value_try (parser, "full-width" - "proportional-width", NULL); - if (ea_values[n_ea]) { - n_ea++; - width = TRUE; + if (_gtk_css_font_variant_caps_value_get (values[2]) == GTK_CSS_FONT_VARIANT_CAPS_NORMAL) + { + _gtk_css_parser_error (parser, "Unexpected caps value"); + return FALSE; + } + goto found; } - } - if (!ruby) + } + + if (values[4] == NULL) { - ea_values[n_ea] = _gtk_css_ident_value_try (parser, "ruby", NULL); - if (ea_values[n_ea]) + values[4] = _gtk_css_font_variant_alternate_value_try_parse (parser); + if (values[4]) { - n_ea++; - ruby = TRUE; + if (_gtk_css_font_variant_alternate_value_get (values[4]) == GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL) + { + _gtk_css_parser_error (parser, "Unexpected alternate value"); + return FALSE; + } + goto found; } - } + } + _gtk_css_parser_error (parser, "Unknown value for property"); + return FALSE; - if (!found) - { - _gtk_css_parser_error (parser, "Unknown value for property"); - return FALSE; - } - } while (!value_is_done_parsing (parser)); +found: + if (value_is_done_parsing (parser)) + break; - if (n_ligs > 0) - values[0] = _gtk_css_array_value_new_from_array (lig_values, n_ligs); + } while (1); - if (n_num > 0) - values[3] = _gtk_css_array_value_new_from_array (num_values, n_num); + if (ligatures != 0) + { + values[0] = _gtk_css_font_variant_ligature_value_new (ligatures); + if (values[0] == NULL) + { + _gtk_css_parser_error (parser, "Invalid combination of ligature values"); + return FALSE; + } + } - if (alt_value) - values[4] = _gtk_css_array_value_new (alt_value); + if (numeric != 0) + { + values[3] = _gtk_css_font_variant_numeric_value_new (numeric); + if (values[3] == NULL) + { + _gtk_css_parser_error (parser, "Invalid combination of numeric values"); + return FALSE; + } + } - if (n_ea > 0) - values[5] = _gtk_css_array_value_new_from_array (ea_values, n_ea); + if (east_asian != 0) + { + values[5] = _gtk_css_font_variant_east_asian_value_new (east_asian); + if (values[5] == NULL) + { + _gtk_css_parser_error (parser, "Invalid combination of east asian values"); + return FALSE; + } + } } return TRUE; diff --git a/gtk/gtkcssstyle.c b/gtk/gtkcssstyle.c index 245d48a428..8cdcd2e6d6 100644 --- a/gtk/gtkcssstyle.c +++ b/gtk/gtkcssstyle.c @@ -216,6 +216,14 @@ add_pango_attr (PangoAttrList *attrs, return attrs; } +static void +append_separated (GString *s, const char *text) +{ + if (s->len > 0) + g_string_append (s, ", "); + g_string_append (s, text); +} + PangoAttrList * gtk_css_style_get_pango_attributes (GtkCssStyle *style) { @@ -225,15 +233,11 @@ gtk_css_style_get_pango_attributes (GtkCssStyle *style) const GdkRGBA *color; const GdkRGBA *decoration_color; gint letter_spacing; - GtkCssValue *kerning; - GtkCssValue *ligatures; - GtkCssValue *position; - GtkCssValue *caps; - GtkCssValue *numeric; - GtkCssValue *alternates; - GtkCssValue *east_asian; + GtkCssValue *value; + GtkCssFontVariantLigature ligatures; + GtkCssFontVariantNumeric numeric; + GtkCssFontVariantEastAsian east_asian; 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)); @@ -273,136 +277,143 @@ gtk_css_style_get_pango_attributes (GtkCssStyle *style) 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) - g_string_append (s, "kern 1"); - else if (strcmp (_gtk_css_ident_value_get (kerning), "none") == 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++) + value = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_KERNING); + switch (_gtk_css_font_kerning_value_get (value)) { - 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"); + case GTK_CSS_FONT_KERNING_NORMAL: + append_separated (s, "kern 1"); + break; + case GTK_CSS_FONT_KERNING_NONE: + append_separated (s, "kern 0"); + break; + default: ; } - position = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_POSITION); - if (strcmp (_gtk_css_ident_value_get (position), "sub") == 0) + value = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_LIGATURES); + ligatures = _gtk_css_font_variant_ligature_value_get (value); + if (ligatures == GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL) { - if (s->len > 0) g_string_append (s, ", "); - g_string_append (s, "subs 1"); + /* all defaults */ } - else if (strcmp (_gtk_css_ident_value_get (kerning), "super") == 0) + else if (ligatures == GTK_CSS_FONT_VARIANT_LIGATURE_NONE) + append_separated (s, "liga 0, clig 0, dlig 0, hlig 0, calt 0"); + else { - if (s->len > 0) g_string_append (s, ", "); - g_string_append (s, "sups 1"); + if (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_COMMON_LIGATURES) + append_separated (s, "liga 1, clig 1"); + if (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_COMMON_LIGATURES) + append_separated (s, "liga 0, clig 0"); + if (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_DISCRETIONARY_LIGATURES) + append_separated (s, "dlig 1"); + if (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_DISCRETIONARY_LIGATURES) + append_separated (s, "dlig 0"); + if (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_HISTORICAL_LIGATURES) + append_separated (s, "hlig 1"); + if (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_HISTORICAL_LIGATURES) + append_separated (s, "hlig 0"); + if (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_CONTEXTUAL) + append_separated (s, "calt 1"); + if (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_CONTEXTUAL) + append_separated (s, "calt 0"); } - caps = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_CAPS); - if (strcmp (_gtk_css_ident_value_get (caps), "small-caps") == 0) - { - if (s->len > 0) g_string_append (s, ", "); - g_string_append (s, "smcp 1"); - } - else if (strcmp (_gtk_css_ident_value_get (caps), "all-small-caps") == 0) - { - if (s->len > 0) g_string_append (s, ", "); - g_string_append (s, "c2sc 1, smcp 1"); - } - else if (strcmp (_gtk_css_ident_value_get (caps), "petite-caps") == 0) + value = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_POSITION); + switch (_gtk_css_font_variant_position_value_get (value)) { - if (s->len > 0) g_string_append (s, ", "); - g_string_append (s, "pcap 1"); + case GTK_CSS_FONT_VARIANT_POSITION_SUB: + append_separated (s, "subs 1"); + break; + case GTK_CSS_FONT_VARIANT_POSITION_SUPER: + append_separated (s, "sups 1"); + break; + default: ; } - else if (strcmp (_gtk_css_ident_value_get (caps), "all-petite-caps") == 0) + + value = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_CAPS); + switch (_gtk_css_font_variant_caps_value_get (value)) { - if (s->len > 0) g_string_append (s, ", "); - g_string_append (s, "c2pc 1, pcap 1"); + case GTK_CSS_FONT_VARIANT_CAPS_SMALL_CAPS: + append_separated (s, "smcp 1"); + break; + case GTK_CSS_FONT_VARIANT_CAPS_ALL_SMALL_CAPS: + append_separated (s, "c2sc 1, smcp 1"); + break; + case GTK_CSS_FONT_VARIANT_CAPS_PETITE_CAPS: + append_separated (s, "pcap 1"); + break; + case GTK_CSS_FONT_VARIANT_CAPS_ALL_PETITE_CAPS: + append_separated (s, "c2pc 1, pcap 1"); + break; + case GTK_CSS_FONT_VARIANT_CAPS_UNICASE: + append_separated (s, "unic 1"); + break; + case GTK_CSS_FONT_VARIANT_CAPS_TITLING_CAPS: + append_separated (s, "titl 1"); + break; + default: ; } - else if (strcmp (_gtk_css_ident_value_get (caps), "unicase") == 0) + + value = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC); + numeric = _gtk_css_font_variant_numeric_value_get (value); + if (numeric == GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL) { - if (s->len > 0) g_string_append (s, ", "); - g_string_append (s, "unic 1"); + /* all defaults */ } - else if (strcmp (_gtk_css_ident_value_get (caps), "titling-caps") == 0) + else { - if (s->len > 0) g_string_append (s, ", "); - g_string_append (s, "titl 1"); + if (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS) + append_separated (s, "lnum 1"); + if (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS) + append_separated (s, "onum 1"); + if (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS) + append_separated (s, "pnum 1"); + if (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS) + append_separated (s, "tnum 1"); + if (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS) + append_separated (s, "frac 1"); + if (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS) + append_separated (s, "afrc 1"); + if (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_ORDINAL) + append_separated (s, "ordn 1"); + if (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO) + append_separated (s, "zero 1"); } - numeric = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC); - for (i = 0; i < _gtk_css_array_value_get_n_values (numeric); i++) + value = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_ALTERNATES); + switch (_gtk_css_font_variant_alternate_value_get (value)) { - GtkCssValue *value = _gtk_css_array_value_get_nth (numeric, i); - if (s->len > 0) g_string_append (s, ", "); - if (strcmp (_gtk_css_ident_value_get (value), "lining-nums") == 0) - g_string_append (s, "lnum 1"); - else if (strcmp (_gtk_css_ident_value_get (value), "oldstyle-nums") == 0) - g_string_append (s, "onum 1"); - else if (strcmp (_gtk_css_ident_value_get (value), "proportional-nums") == 0) - g_string_append (s, "pnum 1"); - else if (strcmp (_gtk_css_ident_value_get (value), "tabular-nums") == 0) - g_string_append (s, "tnum 1"); - else if (strcmp (_gtk_css_ident_value_get (value), "diagonal-fractions") == 0) - g_string_append (s, "frac 1"); - else if (strcmp (_gtk_css_ident_value_get (value), "stacked-fractions") == 0) - g_string_append (s, "afrc 1"); - else if (strcmp (_gtk_css_ident_value_get (value), "ordinal") == 0) - g_string_append (s, "ordn 1"); - else if (strcmp (_gtk_css_ident_value_get (value), "slashed-zero") == 0) - g_string_append (s, "zero 1"); + case GTK_CSS_FONT_VARIANT_ALTERNATE_HISTORICAL_FORMS: + append_separated (s, "hist 1"); + break; + default: ; } - alternates = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_ALTERNATES); - for (i = 0; i < _gtk_css_array_value_get_n_values (alternates); i++) + value = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_EAST_ASIAN); + east_asian = _gtk_css_font_variant_east_asian_value_get (value); + if (east_asian == GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL) { - GtkCssValue *value = _gtk_css_array_value_get_nth (alternates, i); - if (s->len > 0) g_string_append (s, ", "); - if (strcmp (_gtk_css_ident_value_get (value), "historical-forms") == 0) - g_string_append (s, "hist 1"); + /* all defaults */ } - - east_asian = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_EAST_ASIAN); - for (i = 0; i < _gtk_css_array_value_get_n_values (east_asian); i++) + else { - GtkCssValue *value = _gtk_css_array_value_get_nth (east_asian, i); - if (s->len > 0) g_string_append (s, ", "); - if (strcmp (_gtk_css_ident_value_get (value), "jis78") == 0) - g_string_append (s, "jp78 1"); - if (strcmp (_gtk_css_ident_value_get (value), "jis83") == 0) - g_string_append (s, "jp83 1"); - if (strcmp (_gtk_css_ident_value_get (value), "jis90") == 0) - g_string_append (s, "jp90 1"); - if (strcmp (_gtk_css_ident_value_get (value), "jis04") == 0) - g_string_append (s, "jp04 1"); - if (strcmp (_gtk_css_ident_value_get (value), "simplified") == 0) - g_string_append (s, "smpl 1"); - if (strcmp (_gtk_css_ident_value_get (value), "traditional") == 0) - g_string_append (s, "trad 1"); - if (strcmp (_gtk_css_ident_value_get (value), "full-width") == 0) - g_string_append (s, "fwid 1"); - if (strcmp (_gtk_css_ident_value_get (value), "proportional-width") == 0) - g_string_append (s, "pwid 1"); - if (strcmp (_gtk_css_ident_value_get (value), "ruby") == 0) - g_string_append (s, "ruby 1"); + if (east_asian & GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS78) + append_separated (s, "jp78 1"); + if (east_asian & GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS83) + append_separated (s, "jp83 1"); + if (east_asian & GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS90) + append_separated (s, "jp90 1"); + if (east_asian & GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS04) + append_separated (s, "jp04 1"); + if (east_asian & GTK_CSS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED) + append_separated (s, "smpl 1"); + if (east_asian & GTK_CSS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL) + append_separated (s, "trad 1"); + if (east_asian & GTK_CSS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH) + append_separated (s, "fwid 1"); + if (east_asian & GTK_CSS_FONT_VARIANT_EAST_ASIAN_PROPORTIONAL) + append_separated (s, "pwid 1"); + if (east_asian & GTK_CSS_FONT_VARIANT_EAST_ASIAN_RUBY) + append_separated (s, "ruby 1"); } attrs = add_pango_attr (attrs, pango_attr_font_features_new (s->str)); diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c index c791219506..036bd0201f 100644 --- a/gtk/gtkcssstylepropertyimpl.c +++ b/gtk/gtkcssstylepropertyimpl.c @@ -1,4 +1,4 @@ -/* GTK - The GIMP Toolkit +/* * Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org> * * This library is free software; you can redistribute it and/or @@ -513,9 +513,8 @@ static GtkCssValue * parse_font_kerning (GtkCssStyleProperty *property, GtkCssParser *parser) { - GtkCssValue *value = NULL; + GtkCssValue *value = _gtk_css_font_kerning_value_try_parse (parser); - value = _gtk_css_ident_value_try (parser, "auto", "normal", "none", NULL); if (value == NULL) _gtk_css_parser_error (parser, "unknown value for property"); @@ -536,73 +535,24 @@ parse_font_variant_ligatures (GtkCssStyleProperty *property, GtkCssParser *parser) { GtkCssValue *value = NULL; + GtkCssFontVariantLigature ligatures; - 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); - } + ligatures = 0; + do { + GtkCssFontVariantLigature parsed; + + parsed = _gtk_css_font_variant_ligature_try_parse_one (parser, ligatures); + if (parsed == 0 || parsed == ligatures) + { + _gtk_css_parser_error (parser, "Not a valid value"); + return NULL; + } + ligatures = parsed; + } while (!value_is_done_parsing (parser)); + + value = _gtk_css_font_variant_ligature_value_new (ligatures); + if (value == NULL) + _gtk_css_parser_error (parser, "Invalid combination of values"); return value; } @@ -611,9 +561,8 @@ static GtkCssValue * parse_font_variant_position (GtkCssStyleProperty *property, GtkCssParser *parser) { - GtkCssValue *value = NULL; + GtkCssValue *value = _gtk_css_font_variant_position_value_try_parse (parser); - value = _gtk_css_ident_value_try (parser, "normal", "sub", "super", NULL); if (value == NULL) _gtk_css_parser_error (parser, "unknown value for property"); @@ -624,12 +573,8 @@ static GtkCssValue * parse_font_variant_caps (GtkCssStyleProperty *property, GtkCssParser *parser) { - GtkCssValue *value = NULL; + GtkCssValue *value = _gtk_css_font_variant_caps_value_try_parse (parser); - value = _gtk_css_ident_value_try (parser, "normal", - "small-caps", "all-small-caps", - "petite-caps", "all-petite-caps", - "unicase", "titling-caps", NULL); if (value == NULL) _gtk_css_parser_error (parser, "unknown value for property"); @@ -641,76 +586,24 @@ parse_font_variant_numeric (GtkCssStyleProperty *property, GtkCssParser *parser) { GtkCssValue *value = NULL; + GtkCssFontVariantNumeric numeric; - if (_gtk_css_parser_try (parser, "normal", TRUE)) - value = _gtk_css_array_value_new (_gtk_css_ident_value_new ("normal")); - else - { - GtkCssValue *values[5] = { NULL, NULL, NULL, NULL }; - guint n_values = 0; - guint old_n; - gboolean figure = FALSE; - gboolean spacing = FALSE; - gboolean fraction = FALSE; - gboolean ordinal = FALSE; - gboolean zero = FALSE; - - do { - old_n = n_values; - if (!figure) - { - values[n_values] = _gtk_css_ident_value_try (parser, "lining-nums", "oldstyle-nums", NULL); - if (values[n_values]) - { - n_values++; - figure = TRUE; - } - } - if (!spacing) - { - values[n_values] = _gtk_css_ident_value_try (parser, "proportional-nums", "tabular-nums", NULL); - if (values[n_values]) - { - n_values++; - spacing = TRUE; - } - } - if (!fraction) - { - values[n_values] = _gtk_css_ident_value_try (parser, "diagonal-fractions", "stacked-fractions", NULL); - if (values[n_values]) - { - n_values++; - fraction = TRUE; - } - } - if (!ordinal) - { - values[n_values] = _gtk_css_ident_value_try (parser, "ordinal", NULL); - if (values[n_values]) - { - n_values++; - ordinal = TRUE; - } - } - if (!zero) - { - values[n_values] = _gtk_css_ident_value_try (parser, "slashed-zero", NULL); - if (values[n_values]) - { - n_values++; - zero = 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); - } + numeric = 0; + do { + GtkCssFontVariantNumeric parsed; + + parsed = _gtk_css_font_variant_numeric_try_parse_one (parser, numeric); + if (parsed == 0 || parsed == numeric) + { + _gtk_css_parser_error (parser, "Not a valid value"); + return NULL; + } + numeric = parsed; + } while (!value_is_done_parsing (parser)); + + value = _gtk_css_font_variant_numeric_value_new (numeric); + if (value == NULL) + _gtk_css_parser_error (parser, "Invalid combination of values"); return value; } @@ -719,11 +612,10 @@ static GtkCssValue * parse_font_variant_alternates (GtkCssStyleProperty *property, GtkCssParser *parser) { - GtkCssValue *value = NULL; + GtkCssValue *value = _gtk_css_font_variant_alternate_value_try_parse (parser); - value = _gtk_css_ident_value_try (parser, "normal", "historical-forms", NULL); if (value == NULL) - _gtk_css_parser_error (parser, "Not a valid value"); + _gtk_css_parser_error (parser, "unknown value for property"); return value; } @@ -733,63 +625,28 @@ parse_font_variant_east_asian (GtkCssStyleProperty *property, GtkCssParser *parser) { GtkCssValue *value = NULL; + GtkCssFontVariantEastAsian east_asian; - if (_gtk_css_parser_try (parser, "normal", TRUE)) - value = _gtk_css_array_value_new (_gtk_css_ident_value_new ("normal")); - else - { - GtkCssValue *values[3] = { NULL, NULL, NULL }; - guint n_values = 0; - guint old_n; - gboolean variant = FALSE; - gboolean width = FALSE; - gboolean ruby = FALSE; - - do { - old_n = n_values; - if (!variant) - { - values[n_values] = _gtk_css_ident_value_try (parser, "jis78", "jis83", "jis90", "jis04", - "simplified", "traditional", NULL); - if (values[n_values]) - { - n_values++; - variant = TRUE; - } - } - if (!width) - { - values[n_values] = _gtk_css_ident_value_try (parser, "full-width" - "proportional-width", NULL); - if (values[n_values]) - { - n_values++; - width = TRUE; - } - } - if (!ruby) - { - values[n_values] = _gtk_css_ident_value_try (parser, "ruby", NULL); - if (values[n_values]) - { - n_values++; - ruby = 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); - } + east_asian = 0; + do { + GtkCssFontVariantEastAsian parsed; + + parsed = _gtk_css_font_variant_east_asian_try_parse_one (parser, east_asian); + if (parsed == 0 || parsed == east_asian) + { + _gtk_css_parser_error (parser, "Not a valid value"); + return NULL; + } + east_asian = parsed; + } while (!value_is_done_parsing (parser)); + + value = _gtk_css_font_variant_east_asian_value_new (east_asian); + if (value == NULL) + _gtk_css_parser_error (parser, "Invalid combination of values"); return value; } - static GtkCssValue * box_shadow_value_parse (GtkCssStyleProperty *property, GtkCssParser *parser) @@ -1274,7 +1131,7 @@ _gtk_css_style_property_init_properties (void) GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS, parse_font_kerning, NULL, - _gtk_css_ident_value_new ("auto")); + _gtk_css_font_kerning_value_new (GTK_CSS_FONT_KERNING_AUTO)); gtk_css_style_property_register ("font-variant-ligatures", GTK_CSS_PROPERTY_FONT_VARIANT_LIGATURES, G_TYPE_NONE, @@ -1282,7 +1139,7 @@ _gtk_css_style_property_init_properties (void) 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_font_variant_ligature_value_new (GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL)); gtk_css_style_property_register ("font-variant-position", GTK_CSS_PROPERTY_FONT_VARIANT_POSITION, G_TYPE_NONE, @@ -1290,7 +1147,7 @@ _gtk_css_style_property_init_properties (void) GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS, parse_font_variant_position, NULL, - _gtk_css_ident_value_new ("normal")); + _gtk_css_font_variant_position_value_new (GTK_CSS_FONT_VARIANT_POSITION_NORMAL)); gtk_css_style_property_register ("font-variant-caps", GTK_CSS_PROPERTY_FONT_VARIANT_CAPS, G_TYPE_NONE, @@ -1298,7 +1155,7 @@ _gtk_css_style_property_init_properties (void) GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS, parse_font_variant_caps, NULL, - _gtk_css_ident_value_new ("normal")); + _gtk_css_font_variant_caps_value_new (GTK_CSS_FONT_VARIANT_CAPS_NORMAL)); gtk_css_style_property_register ("font-variant-numeric", GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC, G_TYPE_NONE, @@ -1306,7 +1163,7 @@ _gtk_css_style_property_init_properties (void) GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS, parse_font_variant_numeric, NULL, - _gtk_css_array_value_new (_gtk_css_ident_value_new ("normal"))); + _gtk_css_font_variant_numeric_value_new (GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL)); gtk_css_style_property_register ("font-variant-alternates", GTK_CSS_PROPERTY_FONT_VARIANT_ALTERNATES, G_TYPE_NONE, @@ -1314,7 +1171,7 @@ _gtk_css_style_property_init_properties (void) GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS, parse_font_variant_alternates, NULL, - _gtk_css_array_value_new (_gtk_css_ident_value_new ("normal"))); + _gtk_css_font_variant_alternate_value_new (GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL)); gtk_css_style_property_register ("font-variant-east-asian", GTK_CSS_PROPERTY_FONT_VARIANT_EAST_ASIAN, G_TYPE_NONE, @@ -1322,7 +1179,7 @@ _gtk_css_style_property_init_properties (void) GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS, parse_font_variant_east_asian, NULL, - _gtk_css_array_value_new (_gtk_css_ident_value_new ("normal"))); + _gtk_css_font_variant_east_asian_value_new (GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL)); gtk_css_style_property_register ("text-shadow", GTK_CSS_PROPERTY_TEXT_SHADOW, G_TYPE_NONE, diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h index a56c345e32..cae2395985 100644 --- a/gtk/gtkcsstypesprivate.h +++ b/gtk/gtkcsstypesprivate.h @@ -364,6 +364,71 @@ typedef enum /*< skip >*/ { GTK_CSS_MS, } GtkCssUnit; +typedef enum /*< skip >*/ { + GTK_CSS_FONT_KERNING_AUTO, + GTK_CSS_FONT_KERNING_NORMAL, + GTK_CSS_FONT_KERNING_NONE +} GtkCssFontKerning; + +typedef enum /*< skip >*/ { + GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL = 1 << 0, + GTK_CSS_FONT_VARIANT_LIGATURE_NONE = 1 << 1, + GTK_CSS_FONT_VARIANT_LIGATURE_COMMON_LIGATURES = 1 << 2, + GTK_CSS_FONT_VARIANT_LIGATURE_NO_COMMON_LIGATURES = 1 << 3, + GTK_CSS_FONT_VARIANT_LIGATURE_DISCRETIONARY_LIGATURES = 1 << 4, + GTK_CSS_FONT_VARIANT_LIGATURE_NO_DISCRETIONARY_LIGATURES = 1 << 5, + GTK_CSS_FONT_VARIANT_LIGATURE_HISTORICAL_LIGATURES = 1 << 6, + GTK_CSS_FONT_VARIANT_LIGATURE_NO_HISTORICAL_LIGATURES = 1 << 7, + GTK_CSS_FONT_VARIANT_LIGATURE_CONTEXTUAL = 1 << 8, + GTK_CSS_FONT_VARIANT_LIGATURE_NO_CONTEXTUAL = 1 << 9 +} GtkCssFontVariantLigature; + +typedef enum /*< skip >*/ { + GTK_CSS_FONT_VARIANT_POSITION_NORMAL, + GTK_CSS_FONT_VARIANT_POSITION_SUB, + GTK_CSS_FONT_VARIANT_POSITION_SUPER +} GtkCssFontVariantPosition; + +typedef enum /*< skip >*/ { + GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL = 1 << 0, + GTK_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS = 1 << 1, + GTK_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS = 1 << 2, + GTK_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS = 1 << 3, + GTK_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS = 1 << 4, + GTK_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS = 1 << 5, + GTK_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS = 1 << 6, + GTK_CSS_FONT_VARIANT_NUMERIC_ORDINAL = 1 << 7, + GTK_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO = 1 << 8 +} GtkCssFontVariantNumeric; + +typedef enum /*< skip >*/ { + GTK_CSS_FONT_VARIANT_CAPS_NORMAL, + GTK_CSS_FONT_VARIANT_CAPS_SMALL_CAPS, + GTK_CSS_FONT_VARIANT_CAPS_ALL_SMALL_CAPS, + GTK_CSS_FONT_VARIANT_CAPS_PETITE_CAPS, + GTK_CSS_FONT_VARIANT_CAPS_ALL_PETITE_CAPS, + GTK_CSS_FONT_VARIANT_CAPS_UNICASE, + GTK_CSS_FONT_VARIANT_CAPS_TITLING_CAPS +} GtkCssFontVariantCaps; + +typedef enum /*< skip >*/ { + GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL, + GTK_CSS_FONT_VARIANT_ALTERNATE_HISTORICAL_FORMS +} GtkCssFontVariantAlternate; + +typedef enum /*< skip >*/ { + GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL = 1 << 0, + GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS78 = 1 << 1, + GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS83 = 1 << 2, + GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS90 = 1 << 3, + GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS04 = 1 << 4, + GTK_CSS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED = 1 << 5, + GTK_CSS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL = 1 << 6, + GTK_CSS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH = 1 << 7, + GTK_CSS_FONT_VARIANT_EAST_ASIAN_PROPORTIONAL = 1 << 8, + GTK_CSS_FONT_VARIANT_EAST_ASIAN_RUBY = 1 << 9 +} GtkCssFontVariantEastAsian; + cairo_operator_t _gtk_css_blend_mode_get_operator (GskBlendMode mode); GtkCssChange _gtk_css_change_for_sibling (GtkCssChange match); |