LibWeb/CSS: Make font-stretch a legacy alias for new font-width

CSS Fonts level 4 renames font-stretch to font-width, with font-stretch
being left as a legacy alias. Unfortunately the other specs have not yet
been updated, so both terms are used in different places.
This commit is contained in:
Sam Atkins 2024-09-27 14:04:59 +01:00 committed by Andreas Kling
parent 7c50a31402
commit 4a67b28600
Notes: github-actions[bot] 2024-09-28 12:43:39 +00:00
10 changed files with 47 additions and 41 deletions

View file

@ -12,10 +12,10 @@ fill-opacity: 1
fill-rule: nonzero fill-rule: nonzero
font-family: serif font-family: serif
font-size: 16px font-size: 16px
font-stretch: normal
font-style: normal font-style: normal
font-variant: normal font-variant: normal
font-weight: 400 font-weight: 400
font-width: normal
image-rendering: auto image-rendering: auto
letter-spacing: normal letter-spacing: normal
line-height: normal line-height: normal

View file

@ -407,7 +407,7 @@ int CSSStyleValue::to_font_slope() const
return normal_slope; return normal_slope;
} }
int CSSStyleValue::to_font_stretch_width() const int CSSStyleValue::to_font_width() const
{ {
int width = Gfx::FontWidth::Normal; int width = Gfx::FontWidth::Normal;
if (is_keyword()) { if (is_keyword()) {

View file

@ -344,7 +344,7 @@ public:
[[nodiscard]] int to_font_weight() const; [[nodiscard]] int to_font_weight() const;
[[nodiscard]] int to_font_slope() const; [[nodiscard]] int to_font_slope() const;
[[nodiscard]] int to_font_stretch_width() const; [[nodiscard]] int to_font_width() const;
virtual bool equals(CSSStyleValue const& other) const = 0; virtual bool equals(CSSStyleValue const& other) const = 0;

View file

@ -223,6 +223,17 @@
"normal", "normal",
"small-caps" "small-caps"
], ],
"font-width": [
"ultra-condensed",
"extra-condensed",
"condensed",
"semi-condensed",
"normal",
"semi-expanded",
"expanded",
"extra-expanded",
"ultra-expanded"
],
"image-rendering": [ "image-rendering": [
"auto", "auto",
"crisp-edges", "crisp-edges",

View file

@ -261,12 +261,13 @@ WebIDL::ExceptionOr<void> FontFace::set_weight(String const& string)
// https://drafts.csswg.org/css-font-loading/#dom-fontface-stretch // https://drafts.csswg.org/css-font-loading/#dom-fontface-stretch
WebIDL::ExceptionOr<void> FontFace::set_stretch(String const& string) WebIDL::ExceptionOr<void> FontFace::set_stretch(String const& string)
{ {
auto property = parse_property_string<CSS::PropertyID::FontStretch>(realm(), string); // NOTE: font-stretch is now an alias for font-width
auto property = parse_property_string<CSS::PropertyID::FontWidth>(realm(), string);
if (!property) if (!property)
return WebIDL::SyntaxError::create(realm(), "FontFace.stretch setter: Invalid font descriptor"_fly_string); return WebIDL::SyntaxError::create(realm(), "FontFace.stretch setter: Invalid font descriptor"_fly_string);
if (m_is_css_connected) { if (m_is_css_connected) {
// FIXME: Propagate to the CSSFontFaceRule and update the font-stretch property // FIXME: Propagate to the CSSFontFaceRule and update the font-width property
} }
m_stretch = property->to_string(); m_stretch = property->to_string();

View file

@ -5261,7 +5261,7 @@ static bool is_generic_font_family(Keyword keyword)
RefPtr<CSSStyleValue> Parser::parse_font_value(TokenStream<ComponentValue>& tokens) RefPtr<CSSStyleValue> Parser::parse_font_value(TokenStream<ComponentValue>& tokens)
{ {
RefPtr<CSSStyleValue> font_stretch; RefPtr<CSSStyleValue> font_width;
RefPtr<CSSStyleValue> font_style; RefPtr<CSSStyleValue> font_style;
RefPtr<CSSStyleValue> font_weight; RefPtr<CSSStyleValue> font_weight;
RefPtr<CSSStyleValue> font_size; RefPtr<CSSStyleValue> font_size;
@ -5275,7 +5275,9 @@ RefPtr<CSSStyleValue> Parser::parse_font_value(TokenStream<ComponentValue>& toke
// So, we have to handle that separately. // So, we have to handle that separately.
int normal_count = 0; int normal_count = 0;
auto remaining_longhands = Vector { PropertyID::FontSize, PropertyID::FontStretch, PropertyID::FontStyle, PropertyID::FontVariant, PropertyID::FontWeight }; // FIXME: `font-variant` allows a lot of different values which aren't allowed in the `font` shorthand.
// FIXME: `font-width` allows <percentage> values, which aren't allowed in the `font` shorthand.
auto remaining_longhands = Vector { PropertyID::FontSize, PropertyID::FontStyle, PropertyID::FontVariant, PropertyID::FontWeight, PropertyID::FontWidth };
auto transaction = tokens.begin_transaction(); auto transaction = tokens.begin_transaction();
while (tokens.has_next_token()) { while (tokens.has_next_token()) {
@ -5314,13 +5316,12 @@ RefPtr<CSSStyleValue> Parser::parse_font_value(TokenStream<ComponentValue>& toke
font_families = maybe_font_families.release_nonnull(); font_families = maybe_font_families.release_nonnull();
continue; continue;
} }
case PropertyID::FontStretch: { case PropertyID::FontWidth: {
VERIFY(!font_stretch); VERIFY(!font_width);
font_stretch = value.release_nonnull(); font_width = value.release_nonnull();
continue; continue;
} }
case PropertyID::FontStyle: { case PropertyID::FontStyle: {
// FIXME: Handle angle parameter to `oblique`: https://www.w3.org/TR/css-fonts-4/#font-style-prop
VERIFY(!font_style); VERIFY(!font_style);
font_style = value.release_nonnull(); font_style = value.release_nonnull();
continue; continue;
@ -5345,7 +5346,7 @@ RefPtr<CSSStyleValue> Parser::parse_font_value(TokenStream<ComponentValue>& toke
// Since normal is the default value for all the properties that can have it, we don't have to actually // Since normal is the default value for all the properties that can have it, we don't have to actually
// set anything to normal here. It'll be set when we create the ShorthandStyleValue below. // set anything to normal here. It'll be set when we create the ShorthandStyleValue below.
// We just need to make sure we were not given more normals than will fit. // We just need to make sure we were not given more normals than will fit.
int unset_value_count = (font_style ? 0 : 1) + (font_weight ? 0 : 1) + (font_variant ? 0 : 1) + (font_stretch ? 0 : 1); int unset_value_count = (font_style ? 0 : 1) + (font_weight ? 0 : 1) + (font_variant ? 0 : 1) + (font_width ? 0 : 1);
if (unset_value_count < normal_count) if (unset_value_count < normal_count)
return nullptr; return nullptr;
@ -5358,15 +5359,15 @@ RefPtr<CSSStyleValue> Parser::parse_font_value(TokenStream<ComponentValue>& toke
font_variant = property_initial_value(m_context.realm(), PropertyID::FontVariant); font_variant = property_initial_value(m_context.realm(), PropertyID::FontVariant);
if (!font_weight) if (!font_weight)
font_weight = property_initial_value(m_context.realm(), PropertyID::FontWeight); font_weight = property_initial_value(m_context.realm(), PropertyID::FontWeight);
if (!font_stretch) if (!font_width)
font_stretch = property_initial_value(m_context.realm(), PropertyID::FontStretch); font_width = property_initial_value(m_context.realm(), PropertyID::FontWidth);
if (!line_height) if (!line_height)
line_height = property_initial_value(m_context.realm(), PropertyID::LineHeight); line_height = property_initial_value(m_context.realm(), PropertyID::LineHeight);
transaction.commit(); transaction.commit();
return ShorthandStyleValue::create(PropertyID::Font, return ShorthandStyleValue::create(PropertyID::Font,
{ PropertyID::FontStyle, PropertyID::FontVariant, PropertyID::FontWeight, PropertyID::FontStretch, PropertyID::FontSize, PropertyID::LineHeight, PropertyID::FontFamily }, { PropertyID::FontStyle, PropertyID::FontVariant, PropertyID::FontWeight, PropertyID::FontWidth, PropertyID::FontSize, PropertyID::LineHeight, PropertyID::FontFamily },
{ font_style.release_nonnull(), font_variant.release_nonnull(), font_weight.release_nonnull(), font_stretch.release_nonnull(), font_size.release_nonnull(), line_height.release_nonnull(), font_families.release_nonnull() }); { font_style.release_nonnull(), font_variant.release_nonnull(), font_weight.release_nonnull(), font_width.release_nonnull(), font_size.release_nonnull(), line_height.release_nonnull(), font_families.release_nonnull() });
} }
RefPtr<CSSStyleValue> Parser::parse_font_family_value(TokenStream<ComponentValue>& tokens) RefPtr<CSSStyleValue> Parser::parse_font_family_value(TokenStream<ComponentValue>& tokens)

View file

@ -1148,7 +1148,7 @@
"longhands": [ "longhands": [
"font-family", "font-family",
"font-size", "font-size",
"font-stretch", "font-width",
"font-style", "font-style",
"font-variant", "font-variant",
"font-weight", "font-weight",
@ -1191,23 +1191,7 @@
] ]
}, },
"font-stretch": { "font-stretch": {
"animation-type": "custom", "legacy-alias-for": "font-width"
"inherited": true,
"initial": "normal",
"valid-types": [
"percentage [0,∞]"
],
"valid-identifiers": [
"normal",
"ultra-condensed",
"extra-condensed",
"condensed",
"semi-condensed",
"semi-expanded",
"expanded",
"extra-expanded",
"ultra-expanded"
]
}, },
"font-style": { "font-style": {
"animation-type": "custom", "animation-type": "custom",
@ -1241,6 +1225,15 @@
"normal" "normal"
] ]
}, },
"font-width": {
"animation-type": "by-computed-value",
"inherited": true,
"initial": "normal",
"valid-types": [
"percentage [0,∞]",
"font-width"
]
},
"gap": { "gap": {
"inherited": false, "inherited": false,
"initial": "auto", "initial": "auto",

View file

@ -1791,7 +1791,7 @@ RefPtr<Gfx::FontCascadeList const> StyleComputer::compute_font_for_style_values(
{ {
auto* parent_element = element_to_inherit_style_from(element, pseudo_element); auto* parent_element = element_to_inherit_style_from(element, pseudo_element);
auto width = font_stretch.to_font_stretch_width(); auto width = font_stretch.to_font_width();
auto weight = font_weight.to_font_weight(); auto weight = font_weight.to_font_weight();
bool bold = weight > Gfx::FontWeight::Regular; bool bold = weight > Gfx::FontWeight::Regular;
@ -2043,7 +2043,7 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
// FIXME: This should be more sophisticated. // FIXME: This should be more sophisticated.
compute_defaulted_property_value(style, element, CSS::PropertyID::FontFamily, pseudo_element); compute_defaulted_property_value(style, element, CSS::PropertyID::FontFamily, pseudo_element);
compute_defaulted_property_value(style, element, CSS::PropertyID::FontSize, pseudo_element); compute_defaulted_property_value(style, element, CSS::PropertyID::FontSize, pseudo_element);
compute_defaulted_property_value(style, element, CSS::PropertyID::FontStretch, pseudo_element); compute_defaulted_property_value(style, element, CSS::PropertyID::FontWidth, pseudo_element);
compute_defaulted_property_value(style, element, CSS::PropertyID::FontStyle, pseudo_element); compute_defaulted_property_value(style, element, CSS::PropertyID::FontStyle, pseudo_element);
compute_defaulted_property_value(style, element, CSS::PropertyID::FontWeight, pseudo_element); compute_defaulted_property_value(style, element, CSS::PropertyID::FontWeight, pseudo_element);
compute_defaulted_property_value(style, element, CSS::PropertyID::LineHeight, pseudo_element); compute_defaulted_property_value(style, element, CSS::PropertyID::LineHeight, pseudo_element);
@ -2052,9 +2052,9 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
auto font_size = style.property(CSS::PropertyID::FontSize); auto font_size = style.property(CSS::PropertyID::FontSize);
auto font_style = style.property(CSS::PropertyID::FontStyle); auto font_style = style.property(CSS::PropertyID::FontStyle);
auto font_weight = style.property(CSS::PropertyID::FontWeight); auto font_weight = style.property(CSS::PropertyID::FontWeight);
auto font_stretch = style.property(CSS::PropertyID::FontStretch); auto font_width = style.property(CSS::PropertyID::FontWidth);
auto font_list = compute_font_for_style_values(element, pseudo_element, font_family, font_size, font_style, font_weight, font_stretch, style.math_depth()); auto font_list = compute_font_for_style_values(element, pseudo_element, font_family, font_size, font_style, font_weight, font_width, style.math_depth());
VERIFY(font_list); VERIFY(font_list);
VERIFY(!font_list->is_empty()); VERIFY(!font_list->is_empty());

View file

@ -115,7 +115,7 @@ String ShorthandStyleValue::to_string() const
longhand(PropertyID::FontStyle)->to_string(), longhand(PropertyID::FontStyle)->to_string(),
longhand(PropertyID::FontVariant)->to_string(), longhand(PropertyID::FontVariant)->to_string(),
longhand(PropertyID::FontWeight)->to_string(), longhand(PropertyID::FontWeight)->to_string(),
longhand(PropertyID::FontStretch)->to_string(), longhand(PropertyID::FontWidth)->to_string(),
longhand(PropertyID::FontSize)->to_string(), longhand(PropertyID::FontSize)->to_string(),
longhand(PropertyID::LineHeight)->to_string(), longhand(PropertyID::LineHeight)->to_string(),
longhand(PropertyID::FontFamily)->to_string())); longhand(PropertyID::FontFamily)->to_string()));

View file

@ -58,10 +58,10 @@ public:
auto& canvas_element = reinterpret_cast<IncludingClass&>(*this).canvas_element(); auto& canvas_element = reinterpret_cast<IncludingClass&>(*this).canvas_element();
auto& font_style = *font_style_value.longhand(CSS::PropertyID::FontStyle); auto& font_style = *font_style_value.longhand(CSS::PropertyID::FontStyle);
auto& font_weight = *font_style_value.longhand(CSS::PropertyID::FontWeight); auto& font_weight = *font_style_value.longhand(CSS::PropertyID::FontWeight);
auto& font_stretch = *font_style_value.longhand(CSS::PropertyID::FontStretch); auto& font_width = *font_style_value.longhand(CSS::PropertyID::FontWidth);
auto& font_size = *font_style_value.longhand(CSS::PropertyID::FontSize); auto& font_size = *font_style_value.longhand(CSS::PropertyID::FontSize);
auto& font_family = *font_style_value.longhand(CSS::PropertyID::FontFamily); auto& font_family = *font_style_value.longhand(CSS::PropertyID::FontFamily);
auto font_list = canvas_element.document().style_computer().compute_font_for_style_values(&canvas_element, {}, font_family, font_size, font_style, font_weight, font_stretch); auto font_list = canvas_element.document().style_computer().compute_font_for_style_values(&canvas_element, {}, font_family, font_size, font_style, font_weight, font_width);
my_drawing_state().current_font = font_list->first(); my_drawing_state().current_font = font_list->first();
} }