1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 13:38:11 +00:00

LibWeb: Wrap font metrics into a struct

Rather than passing an increasingly-unwieldy number of font parameters
individually to every function that resolves lengths, let's wrap them
up.

This is frustratingly close to being `Gfx::FontPixelMetrics`, but bitmap
fonts cause issues: We choose the closest font to what the CSS
requests, but that might have a wildly different size than what the
page expects, so we have to fudge the numbers.

No behaviour changes.
This commit is contained in:
Sam Atkins 2023-04-28 16:29:12 +01:00 committed by Andreas Kling
parent 4a191875a9
commit 0679b4e0b9
14 changed files with 107 additions and 62 deletions

View file

@ -1049,9 +1049,9 @@ CSSPixels StyleComputer::root_element_font_size() const
auto root_value = computed_root_style->property(CSS::PropertyID::FontSize);
auto font_metrics = computed_root_style->computed_font().pixel_metrics();
auto line_height = font_metrics.line_spacing();
return root_value->to_length().to_px(viewport_rect(), font_metrics, default_root_element_font_size, default_root_element_font_size, line_height, line_height);
auto font_pixel_metrics = computed_root_style->computed_font().pixel_metrics();
Length::FontMetrics font_metrics { default_root_element_font_size, font_pixel_metrics, font_pixel_metrics.line_spacing() };
return root_value->to_length().to_px(viewport_rect(), font_metrics, font_metrics);
}
CSSPixels StyleComputer::root_element_line_height() const
@ -1066,10 +1066,9 @@ CSSPixels StyleComputer::root_element_line_height() const
if (!computed_root_style)
return default_root_element_line_height;
auto font_metrics = computed_root_style->computed_font().pixel_metrics();
auto font_size = root_element_font_size();
auto line_height = font_metrics.line_spacing();
return computed_root_style->line_height(viewport_rect(), font_metrics, font_size, font_size, line_height, line_height);
auto font_pixel_metrics = computed_root_style->computed_font().pixel_metrics();
Length::FontMetrics font_metrics { root_element_font_size(), font_pixel_metrics, font_pixel_metrics.line_spacing() };
return computed_root_style->line_height(viewport_rect(), font_metrics, font_metrics);
}
void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element) const
@ -1218,11 +1217,14 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
auto root_font_size = root_element_font_size();
auto root_line_height = root_element_line_height();
Gfx::FontPixelMetrics font_metrics;
Gfx::FontPixelMetrics font_pixel_metrics;
if (parent_element && parent_element->computed_css_values())
font_metrics = parent_element->computed_css_values()->computed_font().pixel_metrics();
font_pixel_metrics = parent_element->computed_css_values()->computed_font().pixel_metrics();
else
font_metrics = Platform::FontPlugin::the().default_font().pixel_metrics();
font_pixel_metrics = Platform::FontPlugin::the().default_font().pixel_metrics();
// FIXME: Use metrics from root font!!!
Length::FontMetrics root_font_metrics { root_font_size, font_pixel_metrics, root_line_height };
auto parent_font_size = [&]() -> CSSPixels {
if (!parent_element || !parent_element->computed_css_values())
@ -1231,8 +1233,10 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
if (value->is_length()) {
auto length = static_cast<LengthStyleValue const&>(*value).to_length();
auto parent_line_height = parent_or_root_element_line_height(parent_element, {});
if (length.is_absolute() || length.is_relative())
return length.to_px(viewport_rect(), font_metrics, font_size_in_px, root_font_size, parent_line_height, root_line_height);
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, root_font_metrics);
}
}
return font_size_in_px;
};
@ -1251,7 +1255,8 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
}
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(viewport_rect(), font_metrics, parent_font_size(), root_font_size, parent_line_height, root_line_height).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, root_font_metrics).value();
if (px != 0)
font_size_in_px = px;
}
@ -1379,11 +1384,17 @@ CSSPixels StyleComputer::parent_or_root_element_line_height(DOM::Element const*
auto root_font_size = root_element_font_size();
auto root_line_height = root_element_line_height();
auto* computed_values = parent_element->computed_css_values();
auto parent_font_pixel_metrics = parent_element->layout_node()
? parent_element->layout_node()->font().pixel_metrics()
: Gfx::FontDatabase::default_font().pixel_metrics();
auto parent_font_size = computed_values->property(CSS::PropertyID::FontSize)->to_length();
// FIXME: Can the parent font size be non-absolute here?
auto parent_font_size_value = parent_font_size.is_absolute() ? parent_font_size.absolute_length_to_px() : root_font_size;
auto parent_parent_line_height = parent_or_root_element_line_height(parent_element, {});
return computed_values->line_height(viewport_rect(), computed_values->computed_font().pixel_metrics(), parent_font_size_value, root_font_size, parent_parent_line_height, root_line_height);
Length::FontMetrics parent_font_metrics { parent_font_size_value, parent_font_pixel_metrics, parent_parent_line_height };
// FIXME: Use root font metrics!!!
Length::FontMetrics root_font_metrics { root_font_size, parent_font_pixel_metrics, root_line_height };
return computed_values->line_height(viewport_rect(), parent_font_metrics, root_font_metrics);
}
void StyleComputer::absolutize_values(StyleProperties& style, DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element) const
@ -1391,9 +1402,15 @@ void StyleComputer::absolutize_values(StyleProperties& style, DOM::Element const
auto root_line_height = root_element_line_height();
auto parent_or_root_line_height = parent_or_root_element_line_height(element, pseudo_element);
auto font_metrics = style.computed_font().pixel_metrics();
auto font_pixel_metrics = style.computed_font().pixel_metrics();
auto root_font_size = root_element_font_size();
auto font_size = style.property(CSS::PropertyID::FontSize)->to_length().to_px(viewport_rect(), font_metrics, root_font_size, root_font_size, parent_or_root_line_height, root_line_height);
Length::FontMetrics font_metrics { root_font_size, font_pixel_metrics, parent_or_root_line_height };
// FIXME: Use root font metrics!!!
Length::FontMetrics root_font_metrics { root_font_size, font_pixel_metrics, root_line_height };
auto font_size = style.property(CSS::PropertyID::FontSize)->to_length().to_px(viewport_rect(), font_metrics, root_font_metrics);
font_metrics.font_size = font_size;
// NOTE: Percentage line-height values are relative to the font-size of the element.
// We have to resolve them right away, so that the *computed* line-height is ready for inheritance.
@ -1405,7 +1422,8 @@ void StyleComputer::absolutize_values(StyleProperties& style, DOM::Element const
Length::make_px(font_size * line_height_value_slot->as_percentage().percentage().as_fraction()));
}
auto line_height = style.line_height(viewport_rect(), font_metrics, font_size.value(), root_font_size.value(), parent_or_root_line_height, root_line_height);
auto line_height = style.line_height(viewport_rect(), font_metrics, root_font_metrics);
font_metrics.line_height = line_height;
// NOTE: line-height might be using lh which should be resolved against the parent line height (like we did here already)
if (line_height_value_slot && line_height_value_slot->is_length())
@ -1415,7 +1433,7 @@ void StyleComputer::absolutize_values(StyleProperties& style, DOM::Element const
auto& value_slot = style.m_property_values[i];
if (!value_slot)
continue;
value_slot = value_slot->absolutized(viewport_rect(), font_metrics, font_size.value(), root_font_size.value(), line_height, root_line_height);
value_slot = value_slot->absolutized(viewport_rect(), font_metrics, root_font_metrics);
}
}