From 93b643c44d5cb471587cb673e8cfb8f00ae7e2d6 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 31 Mar 2019 20:05:12 +0200 Subject: [PATCH] css: Make font-weight an integer This conforms to what Pango does and to the CSS4 spec. And it makes the parsing code easier. So let's go for it. --- gtk/gtkcssenumvalue.c | 84 +++++-------------- gtk/gtkcssenumvalueprivate.h | 5 +- gtk/gtkcssshorthandpropertyimpl.c | 31 ++++++- gtk/gtkcssstylepropertyimpl.c | 20 ++++- .../css/parser/declarations-valid-04.ref.css | 2 +- testsuite/css/parser/font-weight.ref.css | 8 +- testsuite/css/style/font.nodes | 10 +-- 7 files changed, 78 insertions(+), 82 deletions(-) diff --git a/gtk/gtkcssenumvalue.c b/gtk/gtkcssenumvalue.c index 467c9a568a..6e2828a23d 100644 --- a/gtk/gtkcssenumvalue.c +++ b/gtk/gtkcssenumvalue.c @@ -407,27 +407,27 @@ gtk_css_value_font_weight_compute (GtkCssValue *value, return _gtk_css_value_ref (value); if (parent_style) - parent_value = gtk_css_style_get_value (parent_style, property_id)->value; + parent_value = _gtk_css_number_value_get (gtk_css_style_get_value (parent_style, property_id), 100); else parent_value = 400; if (value->value == BOLDER) { - if (parent_value < 400) - new_weight = PANGO_WEIGHT_NORMAL; - else if (parent_value < 600) - new_weight = PANGO_WEIGHT_BOLD; + if (parent_value < 350) + new_weight = 400; + else if (parent_value < 550) + new_weight = 700; else - new_weight = PANGO_WEIGHT_HEAVY; + new_weight = 900; } else if (value->value == LIGHTER) { - if (parent_value > 700) - new_weight = PANGO_WEIGHT_BOLD; - else if (parent_value > 500) - new_weight = PANGO_WEIGHT_NORMAL; + if (parent_value > 750) + new_weight = 700; + else if (parent_value > 550) + new_weight = 400; else - new_weight = PANGO_WEIGHT_THIN; + new_weight = 100; } else { @@ -435,30 +435,14 @@ gtk_css_value_font_weight_compute (GtkCssValue *value, new_weight = PANGO_WEIGHT_NORMAL; } - return _gtk_css_font_weight_value_new (new_weight); -} - -static GtkCssValue * -gtk_css_value_font_weight_transition (GtkCssValue *start, - GtkCssValue *end, - guint property_id, - double progress) -{ - PangoWeight new_weight; - - if (start->value < 0 || end->value < 0) - return NULL; - - new_weight = (start->value + end->value + 50) / 200 * 100; - - return _gtk_css_font_weight_value_new (new_weight); + return _gtk_css_number_value_new (new_weight, GTK_CSS_NUMBER); } static const GtkCssValueClass GTK_CSS_VALUE_FONT_WEIGHT = { gtk_css_value_enum_free, gtk_css_value_font_weight_compute, gtk_css_value_enum_equal, - gtk_css_value_font_weight_transition, + NULL, NULL, NULL, gtk_css_value_enum_print @@ -467,36 +451,10 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_WEIGHT = { static GtkCssValue font_weight_values[] = { { >K_CSS_VALUE_FONT_WEIGHT, 1, BOLDER, "bolder" }, { >K_CSS_VALUE_FONT_WEIGHT, 1, LIGHTER, "lighter" }, - { >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_THIN, "100" }, - { >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_ULTRALIGHT, "200" }, - { >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_LIGHT, "300" }, - { >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_NORMAL, "normal" }, - { >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_MEDIUM, "500" }, - { >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_SEMIBOLD, "600" }, - { >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_BOLD, "bold" }, - { >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_ULTRABOLD, "800" }, - { >K_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_HEAVY, "900" } }; GtkCssValue * -_gtk_css_font_weight_value_new (PangoWeight font_weight) -{ - guint i; - gint w; - - w = ((font_weight + 50) / 100) * 100; - - for (i = 2; i < G_N_ELEMENTS (font_weight_values); i++) - { - if (font_weight_values[i].value == w) - return _gtk_css_value_ref (&font_weight_values[i]); - } - - g_return_val_if_reached (NULL); -} - -GtkCssValue * -_gtk_css_font_weight_value_try_parse (GtkCssParser *parser) +gtk_css_font_weight_value_try_parse (GtkCssParser *parser) { guint i; @@ -504,20 +462,20 @@ _gtk_css_font_weight_value_try_parse (GtkCssParser *parser) for (i = 0; i < G_N_ELEMENTS (font_weight_values); i++) { - if (_gtk_css_parser_try (parser, font_weight_values[i].name, TRUE)) + if (gtk_css_parser_try_ident (parser, font_weight_values[i].name)) return _gtk_css_value_ref (&font_weight_values[i]); } - /* special cases go here */ - if (_gtk_css_parser_try (parser, "400", TRUE)) - return _gtk_css_value_ref (&font_weight_values[5]); - if (_gtk_css_parser_try (parser, "700", TRUE)) - return _gtk_css_value_ref (&font_weight_values[8]); + + if (gtk_css_parser_try_ident (parser, "normal")) + return _gtk_css_number_value_new (PANGO_WEIGHT_NORMAL, GTK_CSS_NUMBER); + if (gtk_css_parser_try_ident (parser, "bold")) + return _gtk_css_number_value_new (PANGO_WEIGHT_BOLD, GTK_CSS_NUMBER); return NULL; } PangoWeight -_gtk_css_font_weight_value_get (const GtkCssValue *value) +gtk_css_font_weight_value_get (const GtkCssValue *value) { g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_WEIGHT, PANGO_WEIGHT_NORMAL); diff --git a/gtk/gtkcssenumvalueprivate.h b/gtk/gtkcssenumvalueprivate.h index 972ffd96d0..22bab5f1f4 100644 --- a/gtk/gtkcssenumvalueprivate.h +++ b/gtk/gtkcssenumvalueprivate.h @@ -45,9 +45,8 @@ GtkCssValue * _gtk_css_font_style_value_new (PangoStyle style) GtkCssValue * _gtk_css_font_style_value_try_parse (GtkCssParser *parser); PangoStyle _gtk_css_font_style_value_get (const GtkCssValue *value); -GtkCssValue * _gtk_css_font_weight_value_new (PangoWeight weight); -GtkCssValue * _gtk_css_font_weight_value_try_parse (GtkCssParser *parser); -PangoWeight _gtk_css_font_weight_value_get (const GtkCssValue *value); +GtkCssValue * gtk_css_font_weight_value_try_parse (GtkCssParser *parser); +PangoWeight gtk_css_font_weight_value_get (const GtkCssValue *value); GtkCssValue * _gtk_css_font_stretch_value_new (PangoStretch stretch); GtkCssValue * _gtk_css_font_stretch_value_try_parse (GtkCssParser *parser); diff --git a/gtk/gtkcssshorthandpropertyimpl.c b/gtk/gtkcssshorthandpropertyimpl.c index e0712380b9..c553fc9709 100644 --- a/gtk/gtkcssshorthandpropertyimpl.c +++ b/gtk/gtkcssshorthandpropertyimpl.c @@ -450,7 +450,33 @@ parse_font (GtkCssShorthandProperty *shorthand, if (values[3] == NULL) { - values[3] = _gtk_css_font_weight_value_try_parse (parser); + values[3] = gtk_css_font_weight_value_try_parse (parser); + if (values[3] == NULL && gtk_css_number_value_can_parse (parser)) + { + /* This needs to check for font-size, too */ + GtkCssValue *num = _gtk_css_number_value_parse (parser, + GTK_CSS_PARSE_NUMBER | + GTK_CSS_PARSE_LENGTH | + GTK_CSS_PARSE_PERCENT | + GTK_CSS_POSITIVE_ONLY); + if (num == NULL) + return FALSE; + + if (gtk_css_number_value_get_dimension (num) != GTK_CSS_DIMENSION_NUMBER) + { + values[5] = num; + goto have_font_size; + } + + values[3] = num; + if (_gtk_css_number_value_get (values[3], 100) < 1 || + _gtk_css_number_value_get (values[3], 100) > 1000) + { + _gtk_css_parser_error (parser, "Font weight values must be between 1 and 1000"); + g_clear_pointer (&values[3], gtk_css_value_unref); + } + return FALSE; + } parsed_one = parsed_one || values[3] != NULL; } @@ -464,6 +490,7 @@ parse_font (GtkCssShorthandProperty *shorthand, values[5] = gtk_css_font_size_value_parse (parser); +have_font_size: values[0] = gtk_css_font_family_value_parse (parser); return values[0] != NULL && values[5] != NULL; @@ -1119,7 +1146,7 @@ pack_font_description (GtkCssShorthandProperty *shorthand, v = (* query_func) (GTK_CSS_PROPERTY_FONT_WEIGHT, query_data); if (v) - pango_font_description_set_weight (description, _gtk_css_font_weight_value_get (v)); + pango_font_description_set_weight (description, _gtk_css_number_value_get (v, 100)); v = (* query_func) (GTK_CSS_PROPERTY_FONT_STRETCH, query_data); if (v) diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c index a12685655a..a563940896 100644 --- a/gtk/gtkcssstylepropertyimpl.c +++ b/gtk/gtkcssstylepropertyimpl.c @@ -245,10 +245,22 @@ static GtkCssValue * font_weight_parse (GtkCssStyleProperty *property, GtkCssParser *parser) { - GtkCssValue *value = _gtk_css_font_weight_value_try_parse (parser); + GtkCssValue *value; + value = gtk_css_font_weight_value_try_parse (parser); if (value == NULL) - _gtk_css_parser_error (parser, "unknown value for property"); + { + value = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER | GTK_CSS_POSITIVE_ONLY); + + if (value == NULL) + _gtk_css_parser_error (parser, "unknown value for property"); + else if (_gtk_css_number_value_get (value, 100) < 1 || + _gtk_css_number_value_get (value, 100) > 1000) + { + _gtk_css_parser_error (parser, "Font weight values must be between 1 and 1000"); + g_clear_pointer (&value, gtk_css_value_unref); + } + } return value; } @@ -259,7 +271,7 @@ font_weight_query (GtkCssStyleProperty *property, GValue *value) { g_value_init (value, PANGO_TYPE_WEIGHT); - g_value_set_enum (value, _gtk_css_font_weight_value_get (css_value)); + g_value_set_enum (value, _gtk_css_number_value_get (css_value, 100)); } static GtkCssValue * @@ -1004,7 +1016,7 @@ _gtk_css_style_property_init_properties (void) GTK_CSS_AFFECTS_TEXT_SIZE, font_weight_parse, font_weight_query, - _gtk_css_font_weight_value_new (PANGO_WEIGHT_NORMAL)); + _gtk_css_number_value_new (PANGO_WEIGHT_NORMAL, GTK_CSS_NUMBER)); gtk_css_style_property_register ("font-stretch", GTK_CSS_PROPERTY_FONT_STRETCH, PANGO_TYPE_STRETCH, diff --git a/testsuite/css/parser/declarations-valid-04.ref.css b/testsuite/css/parser/declarations-valid-04.ref.css index b8ad2ecc09..b84e72788b 100644 --- a/testsuite/css/parser/declarations-valid-04.ref.css +++ b/testsuite/css/parser/declarations-valid-04.ref.css @@ -4,5 +4,5 @@ font-stretch: initial; font-style: initial; font-variant-caps: initial; - font-weight: bold; + font-weight: 700; } diff --git a/testsuite/css/parser/font-weight.ref.css b/testsuite/css/parser/font-weight.ref.css index 645a231ea8..c9063c05a2 100644 --- a/testsuite/css/parser/font-weight.ref.css +++ b/testsuite/css/parser/font-weight.ref.css @@ -11,11 +11,11 @@ c { } d { - font-weight: normal; + font-weight: 400; } e { - font-weight: bold; + font-weight: 700; } f { @@ -39,7 +39,7 @@ j { } k { - font-weight: normal; + font-weight: 400; } l { @@ -51,7 +51,7 @@ m { } n { - font-weight: bold; + font-weight: 700; } o { diff --git a/testsuite/css/style/font.nodes b/testsuite/css/style/font.nodes index 80db28c206..219d79e9d0 100644 --- a/testsuite/css/style/font.nodes +++ b/testsuite/css/style/font.nodes @@ -4,7 +4,7 @@ font-size: 10px; /* font.css:2:25 */ font-family: "Comic Sans"; /* font.css:2:25 */ font-style: normal; /* font.css:2:25 */ - font-weight: normal; /* font.css:2:25 */ + font-weight: 400; /* font.css:2:25 */ font-stretch: normal; /* font.css:2:25 */ font-variant-caps: normal; /* font.css:2:25 */ @@ -14,27 +14,27 @@ font-size: 13.333333333333334px; /* font.css:10:34 */ font-family: "Cantarell", "sans-serif"; /* font.css:10:34 */ font-style: normal; /* font.css:10:34 */ - font-weight: normal; /* font.css:10:34 */ + font-weight: 400; /* font.css:10:34 */ font-stretch: normal; /* font.css:10:34 */ font-variant-caps: normal; /* font.css:10:34 */ label#label3:dir(ltr) font-size: 8px; /* font.css:14:33 */ font-family: "monospace"; /* font.css:14:33 */ font-style: italic; /* font.css:14:33 */ - font-weight: bold; /* font.css:14:33 */ + font-weight: 700; /* font.css:14:33 */ font-stretch: normal; /* font.css:14:33 */ font-variant-caps: normal; /* font.css:14:33 */ label#label4:dir(ltr) font-size: 8px; /* font.css:18:39 */ font-family: "serif"; /* font.css:18:39 */ font-style: oblique; /* font.css:18:39 */ - font-weight: normal; /* font.css:18:39 */ + font-weight: 400; /* font.css:18:39 */ font-stretch: expanded; /* font.css:18:39 */ font-variant-caps: normal; /* font.css:18:39 */ label#label5:dir(ltr) font-size: 75.590551181102356px; /* font.css:22:27 */ font-family: "21st Century"; /* font.css:22:27 */ font-style: normal; /* font.css:22:27 */ - font-weight: normal; /* font.css:22:27 */ + font-weight: 400; /* font.css:22:27 */ font-stretch: normal; /* font.css:22:27 */ font-variant-caps: normal; /* font.css:22:27 */