Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LibWeb: Improve parsing and serialization of some font properties #3482

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
55 changes: 53 additions & 2 deletions Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2344,9 +2344,60 @@ RefPtr<CSSStyleValue> Parser::parse_font_value(TokenStream<ComponentValue>& toke
line_height = property_initial_value(PropertyID::LineHeight);

transaction.commit();
auto initial_value = CSSKeywordValue::create(Keyword::Initial);
return ShorthandStyleValue::create(PropertyID::Font,
{ 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_width.release_nonnull(), font_size.release_nonnull(), line_height.release_nonnull(), font_families.release_nonnull() });
{
// Set explicitly https://drafts.csswg.org/css-fonts/#set-explicitly
PropertyID::FontFamily,
PropertyID::FontSize,
PropertyID::FontWidth,
// FIXME: PropertyID::FontStretch
PropertyID::FontStyle,
PropertyID::FontVariant,
PropertyID::FontWeight,
PropertyID::LineHeight,

// Reset implicitly https://drafts.csswg.org/css-fonts/#reset-implicitly
PropertyID::FontFeatureSettings,
// FIXME: PropertyID::FontKerning,
PropertyID::FontLanguageOverride,
// FIXME: PropertyID::FontOpticalSizing,
// FIXME: PropertyID::FontSizeAdjust,
PropertyID::FontVariantAlternates,
PropertyID::FontVariantCaps,
PropertyID::FontVariantEastAsian,
PropertyID::FontVariantEmoji,
PropertyID::FontVariantLigatures,
PropertyID::FontVariantNumeric,
PropertyID::FontVariantPosition,
PropertyID::FontVariationSettings,
},
{
// Set explicitly
font_families.release_nonnull(),
font_size.release_nonnull(),
font_width.release_nonnull(),
// FIXME: font-stretch
font_style.release_nonnull(),
font_variant.release_nonnull(),
font_weight.release_nonnull(),
line_height.release_nonnull(),

// Reset implicitly
initial_value, // font-feature-settings
// FIXME: font-kerning,
initial_value, // font-language-override
// FIXME: font-optical-sizing,
// FIXME: font-size-adjust,
initial_value, // font-variant-alternates
initial_value, // font-variant-caps
initial_value, // font-variant-east-asian
initial_value, // font-variant-emoji
initial_value, // font-variant-ligatures
initial_value, // font-variant-numeric
initial_value, // font-variant-position
initial_value, // font-variation-settings
});
}

RefPtr<CSSStyleValue> Parser::parse_font_family_value(TokenStream<ComponentValue>& tokens)
Expand Down
42 changes: 32 additions & 10 deletions Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/*
* Copyright (c) 2023, Ali Mohammad Pur <[email protected]>
* Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2023-2025, Sam Atkins <sam@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include "ShorthandStyleValue.h"
#include <LibGfx/Font/FontWeight.h>
#include <LibWeb/CSS/PropertyID.h>
#include <LibWeb/CSS/StyleValues/BorderRadiusStyleValue.h>
#include <LibWeb/CSS/StyleValues/CSSKeywordValue.h>
Expand Down Expand Up @@ -165,15 +166,36 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
return MUST(String::formatted("{} {} {}", longhand(PropertyID::FlexGrow)->to_string(mode), longhand(PropertyID::FlexShrink)->to_string(mode), longhand(PropertyID::FlexBasis)->to_string(mode)));
case PropertyID::FlexFlow:
return MUST(String::formatted("{} {}", longhand(PropertyID::FlexDirection)->to_string(mode), longhand(PropertyID::FlexWrap)->to_string(mode)));
case PropertyID::Font:
return MUST(String::formatted("{} {} {} {} {} / {} {}",
longhand(PropertyID::FontStyle)->to_string(mode),
longhand(PropertyID::FontVariant)->to_string(mode),
longhand(PropertyID::FontWeight)->to_string(mode),
longhand(PropertyID::FontWidth)->to_string(mode),
longhand(PropertyID::FontSize)->to_string(mode),
longhand(PropertyID::LineHeight)->to_string(mode),
longhand(PropertyID::FontFamily)->to_string(mode)));
case PropertyID::Font: {
auto font_style = longhand(PropertyID::FontStyle);
auto font_variant = longhand(PropertyID::FontVariant);
auto font_weight = longhand(PropertyID::FontWeight);
auto font_width = longhand(PropertyID::FontWidth);
auto font_size = longhand(PropertyID::FontSize);
auto line_height = longhand(PropertyID::LineHeight);
auto font_family = longhand(PropertyID::FontFamily);

StringBuilder builder;
auto append = [&](auto const& string) {
if (!builder.is_empty())
builder.append(' ');
builder.append(string);
};
if (font_style->to_keyword() != Keyword::Normal && font_style->to_keyword() != Keyword::Initial)
append(font_style->to_string(mode));
if (auto variant_string = font_variant->to_string(mode); variant_string != "normal"sv && variant_string != "initial"sv)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this part includes too many font-variant properties, since https://drafts.csswg.org/css-fonts/#font-prop mentions:
Values for the font-variant property can also be included but only those supported in CSS 2.1; none of the font-variant values added in CSS Fonts Levels 3 or 4 can be used in the font shorthand
[<font-variant-css2>] = normal || small-caps

Perhaps a FIXME at least?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah good catch! I'll take a look.

append(variant_string);
if (font_weight->to_font_weight() != Gfx::FontWeight::Regular && font_weight->to_keyword() != Keyword::Initial)
append(font_weight->to_string(mode));
if (font_width->to_keyword() != Keyword::Normal && font_width->to_keyword() != Keyword::Initial)
append(font_width->to_string(mode));
append(font_size->to_string(mode));
if (line_height->to_keyword() != Keyword::Normal && line_height->to_keyword() != Keyword::Initial)
append(MUST(String::formatted("/ {}", line_height->to_string(mode))));
append(font_family->to_string(mode));

return builder.to_string_without_validation();
}
case PropertyID::FontVariant: {
Vector<StringView> values;
auto ligatures_or_null = longhand(PropertyID::FontVariantLigatures)->to_font_variant_ligatures();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ All supported properties and their default values exposed from CSSStyleDeclarati
'flexWrap': 'nowrap'
'flex-wrap': 'nowrap'
'float': 'none'
'font': 'normal normal 400 normal 16px / normal serif'
'font': '16px serif'
'fontFamily': 'serif'
'font-family': 'serif'
'fontFeatureSettings': 'normal'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
font-feature-settings: normal
font-kerning: undefined
font-language-override: normal
font-optical-sizing: undefined
font-size-adjust: undefined
font-variant-alternates: normal
font-variant-caps: normal
font-variant-east-asian: normal
font-variant-emoji: normal
font-variant-ligatures: normal
font-variant-numeric: normal
font-variant-position: normal
font-variation-settings: normal
Loading