mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:47:34 +00:00
LibWeb: Support font-size: calc()
Now that we have a way to resolve calc() lengths without a layout node, we can finally support calc() values in font-size. This wasn't possible before because font-related properties have to be resolved eagerly in StyleComputer due to font-relative CSS length units depending on the computed font being known.
This commit is contained in:
parent
df8a96ee00
commit
7115446995
3 changed files with 38 additions and 25 deletions
7
Tests/LibWeb/Layout/expected/css-font-size-calc.txt
Normal file
7
Tests/LibWeb/Layout/expected/css-font-size-calc.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
|
BlockContainer <html> at (0,0) content-size 800x125.179687 [BFC] children: not-inline
|
||||||
|
BlockContainer <body> at (8,8) content-size 784x109.179687 children: inline
|
||||||
|
line 0 width: 644.628906, height: 109.179687, bottom: 109.179687, baseline: 84.570312
|
||||||
|
frag 0 from TextNode start: 0, length: 13, rect: [8,8 644.628906x109.179687]
|
||||||
|
"Hello friends"
|
||||||
|
TextNode <#text>
|
3
Tests/LibWeb/Layout/input/css-font-size-calc.html
Normal file
3
Tests/LibWeb/Layout/input/css-font-size-calc.html
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<!doctype html><style>
|
||||||
|
body { font-size: calc(100px); }
|
||||||
|
</style>Hello friends
|
|
@ -1757,6 +1757,28 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
|
||||||
// FIXME: Should be based on "user's default font size"
|
// FIXME: Should be based on "user's default font size"
|
||||||
float font_size_in_px = 16;
|
float font_size_in_px = 16;
|
||||||
|
|
||||||
|
auto parent_line_height = parent_or_root_element_line_height(element, pseudo_element);
|
||||||
|
Gfx::FontPixelMetrics font_pixel_metrics;
|
||||||
|
if (parent_element && parent_element->computed_css_values())
|
||||||
|
font_pixel_metrics = parent_element->computed_css_values()->computed_font().pixel_metrics();
|
||||||
|
else
|
||||||
|
font_pixel_metrics = Platform::FontPlugin::the().default_font().pixel_metrics();
|
||||||
|
auto parent_font_size = [&]() -> CSSPixels {
|
||||||
|
if (!parent_element || !parent_element->computed_css_values())
|
||||||
|
return font_size_in_px;
|
||||||
|
auto value = parent_element->computed_css_values()->property(CSS::PropertyID::FontSize);
|
||||||
|
if (value->is_length()) {
|
||||||
|
auto length = value->as_length().length();
|
||||||
|
auto parent_line_height = parent_or_root_element_line_height(parent_element, {});
|
||||||
|
if (length.is_absolute() || length.is_relative()) {
|
||||||
|
Length::FontMetrics font_metrics { font_size_in_px, font_pixel_metrics, parent_line_height };
|
||||||
|
return length.to_px(viewport_rect(), font_metrics, m_root_element_font_metrics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return font_size_in_px;
|
||||||
|
};
|
||||||
|
Length::FontMetrics font_metrics { parent_font_size(), font_pixel_metrics, parent_line_height };
|
||||||
|
|
||||||
if (font_size->is_identifier()) {
|
if (font_size->is_identifier()) {
|
||||||
// https://w3c.github.io/csswg-drafts/css-fonts/#absolute-size-mapping
|
// https://w3c.github.io/csswg-drafts/css-fonts/#absolute-size-mapping
|
||||||
AK::HashMap<Web::CSS::ValueID, float> absolute_size_mapping = {
|
AK::HashMap<Web::CSS::ValueID, float> absolute_size_mapping = {
|
||||||
|
@ -1787,25 +1809,10 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
|
||||||
font_size_in_px *= multiplier;
|
font_size_in_px *= multiplier;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Gfx::FontPixelMetrics font_pixel_metrics;
|
Length::ResolutionContext const length_resolution_context {
|
||||||
if (parent_element && parent_element->computed_css_values())
|
.viewport_rect = viewport_rect(),
|
||||||
font_pixel_metrics = parent_element->computed_css_values()->computed_font().pixel_metrics();
|
.font_metrics = font_metrics,
|
||||||
else
|
.root_font_metrics = m_root_element_font_metrics,
|
||||||
font_pixel_metrics = Platform::FontPlugin::the().default_font().pixel_metrics();
|
|
||||||
|
|
||||||
auto parent_font_size = [&]() -> CSSPixels {
|
|
||||||
if (!parent_element || !parent_element->computed_css_values())
|
|
||||||
return font_size_in_px;
|
|
||||||
auto value = parent_element->computed_css_values()->property(CSS::PropertyID::FontSize);
|
|
||||||
if (value->is_length()) {
|
|
||||||
auto length = value->as_length().length();
|
|
||||||
auto parent_line_height = parent_or_root_element_line_height(parent_element, {});
|
|
||||||
if (length.is_absolute() || length.is_relative()) {
|
|
||||||
Length::FontMetrics font_metrics { font_size_in_px, font_pixel_metrics, parent_line_height };
|
|
||||||
return length.to_px(viewport_rect(), font_metrics, m_root_element_font_metrics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return font_size_in_px;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Optional<Length> maybe_length;
|
Optional<Length> maybe_length;
|
||||||
|
@ -1815,15 +1822,11 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
|
||||||
|
|
||||||
} else if (font_size->is_length()) {
|
} else if (font_size->is_length()) {
|
||||||
maybe_length = font_size->as_length().length();
|
maybe_length = font_size->as_length().length();
|
||||||
|
|
||||||
} else if (font_size->is_calculated()) {
|
} else if (font_size->is_calculated()) {
|
||||||
// FIXME: Support font-size: calc(...)
|
maybe_length = font_size->as_calculated().resolve_length(length_resolution_context);
|
||||||
// Theoretically we can do this now, but to resolve it we need a layout_node which we might not have. :^(
|
|
||||||
}
|
}
|
||||||
if (maybe_length.has_value()) {
|
if (maybe_length.has_value()) {
|
||||||
auto parent_line_height = parent_or_root_element_line_height(element, pseudo_element);
|
auto px = maybe_length.value().to_px(length_resolution_context).value();
|
||||||
Length::FontMetrics font_metrics { parent_font_size(), font_pixel_metrics, parent_line_height };
|
|
||||||
auto px = maybe_length.value().to_px(viewport_rect(), font_metrics, m_root_element_font_metrics).value();
|
|
||||||
if (px != 0)
|
if (px != 0)
|
||||||
font_size_in_px = px;
|
font_size_in_px = px;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue