mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 21:07:35 +00:00
LibWeb: Implement and use FontStyleValue
After working with the code for a while, it makes more sense to put all the parsing in Parser, instead of some of it living in StyleResolver. That means our current ValueListStyleValue needs to be replaced with specific StyleValue types for the properties that are shorthands or otherwise combine several values together. Here we implement FontStyleProperty, which represents a `font` CSS property. Also adjusted the fonts.html test page so that font-weights are featured in test cases without things we do not yet support.
This commit is contained in:
parent
5e1fad2dff
commit
59501f1940
5 changed files with 247 additions and 164 deletions
|
@ -326,76 +326,6 @@ static inline bool is_font_family(StyleValue const& value)
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool is_font_size(StyleValue const& value)
|
||||
{
|
||||
if (value.is_builtin_or_dynamic())
|
||||
return true;
|
||||
if (value.is_length())
|
||||
return true;
|
||||
switch (value.to_identifier()) {
|
||||
case ValueID::XxSmall:
|
||||
case ValueID::XSmall:
|
||||
case ValueID::Small:
|
||||
case ValueID::Medium:
|
||||
case ValueID::Large:
|
||||
case ValueID::XLarge:
|
||||
case ValueID::XxLarge:
|
||||
case ValueID::XxxLarge:
|
||||
case ValueID::Smaller:
|
||||
case ValueID::Larger:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool is_font_style(StyleValue const& value)
|
||||
{
|
||||
// FIXME: Handle angle parameter to `oblique`: https://www.w3.org/TR/css-fonts-4/#font-style-prop
|
||||
if (value.is_builtin_or_dynamic())
|
||||
return true;
|
||||
switch (value.to_identifier()) {
|
||||
case ValueID::Normal:
|
||||
case ValueID::Italic:
|
||||
case ValueID::Oblique:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool is_font_weight(StyleValue const& value)
|
||||
{
|
||||
if (value.is_builtin_or_dynamic())
|
||||
return true;
|
||||
if (value.is_numeric()) {
|
||||
auto weight = static_cast<NumericStyleValue const&>(value).value();
|
||||
return (weight >= 1 && weight <= 1000);
|
||||
}
|
||||
switch (value.to_identifier()) {
|
||||
case ValueID::Normal:
|
||||
case ValueID::Bold:
|
||||
case ValueID::Bolder:
|
||||
case ValueID::Lighter:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool is_line_height(StyleValue const& value)
|
||||
{
|
||||
if (value.is_builtin_or_dynamic())
|
||||
return true;
|
||||
if (value.is_numeric())
|
||||
return true;
|
||||
if (value.is_length())
|
||||
return true;
|
||||
if (value.to_identifier() == ValueID::Normal)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool is_line_style(StyleValue const& value)
|
||||
{
|
||||
if (value.is_builtin_or_dynamic())
|
||||
|
@ -1096,103 +1026,27 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope
|
|||
}
|
||||
|
||||
if (property_id == CSS::PropertyID::Font) {
|
||||
if (value.is_component_value_list()) {
|
||||
auto parts = static_cast<CSS::ValueListStyleValue const&>(value).values();
|
||||
|
||||
RefPtr<StyleValue> font_style_value;
|
||||
RefPtr<StyleValue> font_weight_value;
|
||||
RefPtr<StyleValue> font_size_value;
|
||||
RefPtr<StyleValue> line_height_value;
|
||||
RefPtr<StyleValue> font_family_value;
|
||||
// FIXME: Implement font-stretch and font-variant.
|
||||
|
||||
for (size_t i = 0; i < parts.size(); ++i) {
|
||||
auto value = Parser::parse_css_value(context, property_id, parts[i]);
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
if (is_font_style(*value)) {
|
||||
if (font_style_value)
|
||||
return;
|
||||
font_style_value = move(value);
|
||||
continue;
|
||||
}
|
||||
if (is_font_weight(*value)) {
|
||||
if (font_weight_value)
|
||||
return;
|
||||
font_weight_value = move(value);
|
||||
continue;
|
||||
}
|
||||
if (is_font_size(*value)) {
|
||||
if (font_size_value)
|
||||
return;
|
||||
font_size_value = move(value);
|
||||
|
||||
// Consume `/ line-height` if present
|
||||
if (i + 2 < parts.size()) {
|
||||
auto solidus_part = parts[i + 1];
|
||||
if (!(solidus_part.is(Token::Type::Delim) && solidus_part.token().delim() == "/"sv))
|
||||
break;
|
||||
auto line_height = Parser::parse_css_value(context, property_id, parts[i + 2]);
|
||||
if (!(line_height && is_line_height(*line_height)))
|
||||
return;
|
||||
line_height_value = move(line_height);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
// Consume font-family
|
||||
// FIXME: Handle multiple font-families separated by commas, for fallback purposes.
|
||||
if (i + 1 < parts.size()) {
|
||||
auto& font_family_part = parts[i + 1];
|
||||
auto font_family = Parser::parse_css_value(context, property_id, font_family_part);
|
||||
if (!font_family) {
|
||||
// Single-word font-families may not be quoted. We convert it to a String for convenience.
|
||||
if (font_family_part.is(Token::Type::Ident))
|
||||
font_family = StringStyleValue::create(font_family_part.token().ident());
|
||||
else
|
||||
return;
|
||||
} else if (!is_font_family(*font_family)) {
|
||||
dbgln("*** Unable to parse '{}' as a font-family.", font_family_part.to_debug_string());
|
||||
return;
|
||||
}
|
||||
|
||||
font_family_value = move(font_family);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!font_size_value || !font_family_value)
|
||||
return;
|
||||
|
||||
style.set_property(CSS::PropertyID::FontSize, *font_size_value);
|
||||
style.set_property(CSS::PropertyID::FontFamily, *font_family_value);
|
||||
|
||||
if (font_style_value)
|
||||
style.set_property(CSS::PropertyID::FontStyle, *font_style_value);
|
||||
if (font_weight_value)
|
||||
style.set_property(CSS::PropertyID::FontWeight, *font_weight_value);
|
||||
if (line_height_value)
|
||||
style.set_property(CSS::PropertyID::LineHeight, *line_height_value);
|
||||
|
||||
if (value.is_font()) {
|
||||
auto& font_shorthand = static_cast<CSS::FontStyleValue const&>(value);
|
||||
style.set_property(CSS::PropertyID::FontSize, font_shorthand.font_size());
|
||||
// FIXME: Support multiple font-families
|
||||
style.set_property(CSS::PropertyID::FontFamily, font_shorthand.font_families().first());
|
||||
style.set_property(CSS::PropertyID::FontStyle, font_shorthand.font_style());
|
||||
style.set_property(CSS::PropertyID::FontWeight, font_shorthand.font_weight());
|
||||
style.set_property(CSS::PropertyID::LineHeight, font_shorthand.line_height());
|
||||
// FIXME: Implement font-stretch and font-variant
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.is_inherit()) {
|
||||
if (value.is_builtin()) {
|
||||
style.set_property(CSS::PropertyID::FontSize, value);
|
||||
// FIXME: Support multiple font-families
|
||||
style.set_property(CSS::PropertyID::FontFamily, value);
|
||||
style.set_property(CSS::PropertyID::FontStyle, value);
|
||||
style.set_property(CSS::PropertyID::FontVariant, value);
|
||||
style.set_property(CSS::PropertyID::FontWeight, value);
|
||||
style.set_property(CSS::PropertyID::LineHeight, value);
|
||||
// FIXME: Implement font-stretch
|
||||
// FIXME: Implement font-stretch and font-variant
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: Handle system fonts. (caption, icon, menu, message-box, small-caption, status-bar)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1211,11 +1065,7 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_font_family(value)) {
|
||||
style.set_property(CSS::PropertyID::FontFamily, value);
|
||||
return;
|
||||
}
|
||||
|
||||
style.set_property(CSS::PropertyID::FontFamily, value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue