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.
This commit is contained in:
Benjamin Otte 2019-03-31 20:05:12 +02:00
parent 21616f6e2e
commit 93b643c44d
7 changed files with 78 additions and 82 deletions

View File

@ -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[] = {
{ &GTK_CSS_VALUE_FONT_WEIGHT, 1, BOLDER, "bolder" },
{ &GTK_CSS_VALUE_FONT_WEIGHT, 1, LIGHTER, "lighter" },
{ &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_THIN, "100" },
{ &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_ULTRALIGHT, "200" },
{ &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_LIGHT, "300" },
{ &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_NORMAL, "normal" },
{ &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_MEDIUM, "500" },
{ &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_SEMIBOLD, "600" },
{ &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_BOLD, "bold" },
{ &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_ULTRABOLD, "800" },
{ &GTK_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 == &GTK_CSS_VALUE_FONT_WEIGHT, PANGO_WEIGHT_NORMAL);

View File

@ -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);

View File

@ -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)

View File

@ -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)
{
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,

View File

@ -4,5 +4,5 @@
font-stretch: initial;
font-style: initial;
font-variant-caps: initial;
font-weight: bold;
font-weight: 700;
}

View File

@ -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 {

View File

@ -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 */