LibWeb: Resolve percentages in calc() for font-size

Fixes crashing on https://react.dev/
This commit is contained in:
Aliaksandr Kalenik 2023-10-04 16:24:24 +02:00 committed by Andreas Kling
parent b64ed060d8
commit 28c9015bd8
5 changed files with 39 additions and 18 deletions

View file

@ -0,0 +1,17 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x105.21875 children: not-inline
BlockContainer <div.test> at (8,8) content-size 784x105.21875 children: inline
line 0 width: 500.8125, height: 52.40625, bottom: 52.40625, baseline: 40.59375
frag 0 from TextNode start: 0, length: 20, rect: [8,8 500.8125x52.40625]
"i resolved enough of"
line 1 width: 406.40625, height: 52.8125, bottom: 105.21875, baseline: 40.59375
frag 0 from TextNode start: 21, length: 16, rect: [8,60 406.40625x52.40625]
"percentages, no?"
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x105.21875]
PaintableWithLines (BlockContainer<DIV>.test) [8,8 784x105.21875]
TextPaintable (TextNode<#text>)

View file

@ -0,0 +1,5 @@
<style>
.test {
font-size: calc(1em + 200%);
}
</style><div class="test">i resolved enough of percentages, no?</div>

View file

@ -1764,7 +1764,11 @@ RefPtr<Gfx::Font const> StyleComputer::compute_font_for_style_values(DOM::Elemen
} else if (font_size.is_length()) {
maybe_length = font_size.as_length().length();
} else if (font_size.is_calculated()) {
maybe_length = font_size.as_calculated().resolve_length(length_resolution_context);
if (font_size.as_calculated().contains_percentage()) {
maybe_length = font_size.as_calculated().resolve_length_percentage(length_resolution_context, Length::make_px(parent_font_size()));
} else {
maybe_length = font_size.as_calculated().resolve_length(length_resolution_context);
}
}
if (maybe_length.has_value()) {
font_size_in_px = maybe_length.value().to_px(length_resolution_context);

View file

@ -2371,7 +2371,17 @@ Optional<Length> CalculatedStyleValue::resolve_length(Layout::Node const& layout
Optional<Length> CalculatedStyleValue::resolve_length_percentage(Layout::Node const& layout_node, Length const& percentage_basis) const
{
auto result = m_calculation->resolve(Length::ResolutionContext::for_layout_node(layout_node), percentage_basis);
return resolve_length_percentage(Length::ResolutionContext::for_layout_node(layout_node), percentage_basis);
}
Optional<Length> CalculatedStyleValue::resolve_length_percentage(Layout::Node const& layout_node, CSSPixels percentage_basis) const
{
return resolve_length_percentage(Length::ResolutionContext::for_layout_node(layout_node), Length::make_px(percentage_basis));
}
Optional<Length> CalculatedStyleValue::resolve_length_percentage(Length::ResolutionContext const& resolution_context, Length const& percentage_basis) const
{
auto result = m_calculation->resolve(resolution_context, percentage_basis);
return result.value().visit(
[&](Length const& length) -> Optional<Length> {
@ -2385,22 +2395,6 @@ Optional<Length> CalculatedStyleValue::resolve_length_percentage(Layout::Node co
});
}
Optional<Length> CalculatedStyleValue::resolve_length_percentage(Layout::Node const& layout_node, CSSPixels percentage_basis) const
{
auto result = m_calculation->resolve(Length::ResolutionContext::for_layout_node(layout_node), Length::make_px(percentage_basis));
return result.value().visit(
[&](Length const& length) -> Optional<Length> {
return length;
},
[&](Percentage const& percentage) -> Optional<Length> {
return Length::make_px(CSSPixels(percentage.value() * percentage_basis) / 100);
},
[&](auto const&) -> Optional<Length> {
return {};
});
}
Optional<Percentage> CalculatedStyleValue::resolve_percentage() const
{
auto result = m_calculation->resolve({}, {});

View file

@ -95,6 +95,7 @@ public:
Optional<Length> resolve_length(Layout::Node const& layout_node) const;
Optional<Length> resolve_length_percentage(Layout::Node const&, Length const& percentage_basis) const;
Optional<Length> resolve_length_percentage(Layout::Node const&, CSSPixels percentage_basis) const;
Optional<Length> resolve_length_percentage(Length::ResolutionContext const&, Length const& percentage_basis) const;
bool resolves_to_percentage() const { return m_resolved_type.matches_percentage(); }
Optional<Percentage> resolve_percentage() const;