mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 19:37:34 +00:00
LibWeb: Add CSSPixels::nearest_value_for(FloatingPoint)
This is intended to annotate conversions from unknown floating-point values to CSSPixels, and make it more obvious the fp value will be rounded to the nearest fixed-point value.
This commit is contained in:
parent
360c0eb509
commit
71baa8c31a
28 changed files with 120 additions and 112 deletions
|
@ -61,31 +61,31 @@ CSSPixels Length::font_relative_length_to_px(Length::FontMetrics const& font_met
|
|||
{
|
||||
switch (m_type) {
|
||||
case Type::Em:
|
||||
return CSSPixels(m_value * font_metrics.font_size.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.font_size.to_double());
|
||||
case Type::Rem:
|
||||
return CSSPixels(m_value * root_font_metrics.font_size.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.font_size.to_double());
|
||||
case Type::Ex:
|
||||
return CSSPixels(m_value * font_metrics.x_height.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.x_height.to_double());
|
||||
case Type::Rex:
|
||||
return CSSPixels(m_value * root_font_metrics.x_height.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.x_height.to_double());
|
||||
case Type::Cap:
|
||||
return CSSPixels(m_value * font_metrics.cap_height.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.cap_height.to_double());
|
||||
case Type::Rcap:
|
||||
return CSSPixels(m_value * root_font_metrics.cap_height.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.cap_height.to_double());
|
||||
case Type::Ch:
|
||||
return CSSPixels(m_value * font_metrics.zero_advance.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.zero_advance.to_double());
|
||||
case Type::Rch:
|
||||
return CSSPixels(m_value * root_font_metrics.zero_advance.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.zero_advance.to_double());
|
||||
case Type::Ic:
|
||||
// FIXME: Use the "advance measure of the “水” (CJK water ideograph, U+6C34) glyph"
|
||||
return CSSPixels(m_value * font_metrics.font_size.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.font_size.to_double());
|
||||
case Type::Ric:
|
||||
// FIXME: Use the "advance measure of the “水” (CJK water ideograph, U+6C34) glyph"
|
||||
return CSSPixels(m_value * root_font_metrics.font_size.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.font_size.to_double());
|
||||
case Type::Lh:
|
||||
return CSSPixels(m_value * font_metrics.line_height.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * font_metrics.line_height.to_double());
|
||||
case Type::Rlh:
|
||||
return CSSPixels(m_value * root_font_metrics.line_height.to_double());
|
||||
return CSSPixels::nearest_value_for(m_value * root_font_metrics.line_height.to_double());
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
@ -98,34 +98,34 @@ CSSPixels Length::viewport_relative_length_to_px(CSSPixelRect const& viewport_re
|
|||
case Type::Svw:
|
||||
case Type::Lvw:
|
||||
case Type::Dvw:
|
||||
return CSSPixels(viewport_rect.width() * (m_value / 100));
|
||||
return CSSPixels::nearest_value_for(viewport_rect.width() * (m_value / 100));
|
||||
case Type::Vh:
|
||||
case Type::Svh:
|
||||
case Type::Lvh:
|
||||
case Type::Dvh:
|
||||
return CSSPixels(viewport_rect.height() * (m_value / 100));
|
||||
return CSSPixels::nearest_value_for(viewport_rect.height() * (m_value / 100));
|
||||
case Type::Vi:
|
||||
case Type::Svi:
|
||||
case Type::Lvi:
|
||||
case Type::Dvi:
|
||||
// FIXME: Select the width or height based on which is the inline axis.
|
||||
return CSSPixels(viewport_rect.width() * (m_value / 100));
|
||||
return CSSPixels::nearest_value_for(viewport_rect.width() * (m_value / 100));
|
||||
case Type::Vb:
|
||||
case Type::Svb:
|
||||
case Type::Lvb:
|
||||
case Type::Dvb:
|
||||
// FIXME: Select the width or height based on which is the block axis.
|
||||
return CSSPixels(viewport_rect.height() * (m_value / 100));
|
||||
return CSSPixels::nearest_value_for(viewport_rect.height() * (m_value / 100));
|
||||
case Type::Vmin:
|
||||
case Type::Svmin:
|
||||
case Type::Lvmin:
|
||||
case Type::Dvmin:
|
||||
return CSSPixels(min(viewport_rect.width(), viewport_rect.height()) * (m_value / 100));
|
||||
return CSSPixels::nearest_value_for(min(viewport_rect.width(), viewport_rect.height()) * (m_value / 100));
|
||||
case Type::Vmax:
|
||||
case Type::Svmax:
|
||||
case Type::Lvmax:
|
||||
case Type::Dvmax:
|
||||
return CSSPixels(max(viewport_rect.width(), viewport_rect.height()) * (m_value / 100));
|
||||
return CSSPixels::nearest_value_for(max(viewport_rect.width(), viewport_rect.height()) * (m_value / 100));
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
@ -138,8 +138,8 @@ Length::ResolutionContext Length::ResolutionContext::for_layout_node(Layout::Nod
|
|||
VERIFY(root_element->layout_node());
|
||||
return Length::ResolutionContext {
|
||||
.viewport_rect = node.browsing_context().viewport_rect(),
|
||||
.font_metrics = { CSSPixels(node.computed_values().font_size()), node.font().pixel_metrics(), node.line_height() },
|
||||
.root_font_metrics = { CSSPixels(root_element->layout_node()->computed_values().font_size()), root_element->layout_node()->font().pixel_metrics(), root_element->layout_node()->line_height() },
|
||||
.font_metrics = { CSSPixels::nearest_value_for(node.computed_values().font_size()), node.font().pixel_metrics(), node.line_height() },
|
||||
.root_font_metrics = { CSSPixels::nearest_value_for(root_element->layout_node()->computed_values().font_size()), root_element->layout_node()->font().pixel_metrics(), root_element->layout_node()->line_height() },
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -168,12 +168,12 @@ CSSPixels Length::to_px(Layout::Node const& layout_node) const
|
|||
return 0;
|
||||
|
||||
FontMetrics font_metrics {
|
||||
CSSPixels(layout_node.computed_values().font_size()),
|
||||
CSSPixels::nearest_value_for(layout_node.computed_values().font_size()),
|
||||
layout_node.font().pixel_metrics(),
|
||||
layout_node.line_height()
|
||||
};
|
||||
FontMetrics root_font_metrics {
|
||||
CSSPixels(root_element->layout_node()->computed_values().font_size()),
|
||||
CSSPixels::nearest_value_for(root_element->layout_node()->computed_values().font_size()),
|
||||
root_element->layout_node()->font().pixel_metrics(),
|
||||
root_element->layout_node()->line_height()
|
||||
};
|
||||
|
|
|
@ -185,19 +185,19 @@ public:
|
|||
constexpr double centimeter_pixels = (inch_pixels / 2.54);
|
||||
switch (m_type) {
|
||||
case Type::Cm:
|
||||
return CSSPixels(m_value * centimeter_pixels); // 1cm = 96px/2.54
|
||||
return CSSPixels::nearest_value_for(m_value * centimeter_pixels); // 1cm = 96px/2.54
|
||||
case Type::In:
|
||||
return CSSPixels(m_value * inch_pixels); // 1in = 2.54 cm = 96px
|
||||
return CSSPixels::nearest_value_for(m_value * inch_pixels); // 1in = 2.54 cm = 96px
|
||||
case Type::Px:
|
||||
return CSSPixels(m_value); // 1px = 1/96th of 1in
|
||||
return CSSPixels::nearest_value_for(m_value); // 1px = 1/96th of 1in
|
||||
case Type::Pt:
|
||||
return CSSPixels(m_value * ((1.0 / 72.0) * inch_pixels)); // 1pt = 1/72th of 1in
|
||||
return CSSPixels::nearest_value_for(m_value * ((1.0 / 72.0) * inch_pixels)); // 1pt = 1/72th of 1in
|
||||
case Type::Pc:
|
||||
return CSSPixels(m_value * ((1.0 / 6.0) * inch_pixels)); // 1pc = 1/6th of 1in
|
||||
return CSSPixels::nearest_value_for(m_value * ((1.0 / 6.0) * inch_pixels)); // 1pc = 1/6th of 1in
|
||||
case Type::Mm:
|
||||
return CSSPixels(m_value * ((1.0 / 10.0) * centimeter_pixels)); // 1mm = 1/10th of 1cm
|
||||
return CSSPixels::nearest_value_for(m_value * ((1.0 / 10.0) * centimeter_pixels)); // 1mm = 1/10th of 1cm
|
||||
case Type::Q:
|
||||
return CSSPixels(m_value * ((1.0 / 40.0) * centimeter_pixels)); // 1Q = 1/40th of 1cm
|
||||
return CSSPixels::nearest_value_for(m_value * ((1.0 / 40.0) * centimeter_pixels)); // 1Q = 1/40th of 1cm
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ bool MediaFeature::compare(HTML::Window const& window, MediaFeatureValue left, C
|
|||
|
||||
auto const& initial_font = window.associated_document().style_computer().initial_font();
|
||||
Gfx::FontPixelMetrics const& initial_font_metrics = initial_font.pixel_metrics();
|
||||
Length::FontMetrics font_metrics { CSSPixels(initial_font.presentation_size()), initial_font_metrics, CSSPixels(initial_font_metrics.line_spacing()) };
|
||||
Length::FontMetrics font_metrics { initial_font.presentation_size(), initial_font_metrics, CSSPixels::nearest_value_for(initial_font_metrics.line_spacing()) };
|
||||
|
||||
left_px = left.length().to_px(viewport_rect, font_metrics, font_metrics);
|
||||
right_px = right.length().to_px(viewport_rect, font_metrics, font_metrics);
|
||||
|
|
|
@ -1787,7 +1787,7 @@ Optional<Dimension> Parser::parse_dimension(ComponentValue const& component_valu
|
|||
// FIXME: Disallow quirk when inside a CSS sub-expression (like `calc()`)
|
||||
// "The <quirky-length> value must not be supported in arguments to CSS expressions other than the rect()
|
||||
// expression, and must not be supported in the supports() static method of the CSS interface."
|
||||
return Length::make_px(CSSPixels(numeric_value));
|
||||
return Length::make_px(CSSPixels::nearest_value_for(numeric_value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -596,7 +596,7 @@ RefPtr<StyleValue const> ResolvedCSSStyleDeclaration::style_value_for_property(L
|
|||
case PropertyID::Float:
|
||||
return IdentifierStyleValue::create(to_value_id(layout_node.computed_values().float_()));
|
||||
case PropertyID::FontSize:
|
||||
return LengthStyleValue::create(Length::make_px(CSSPixels(layout_node.computed_values().font_size())));
|
||||
return LengthStyleValue::create(Length::make_px(CSSPixels::nearest_value_for(layout_node.computed_values().font_size())));
|
||||
case PropertyID::FontVariant: {
|
||||
auto font_variant = layout_node.computed_values().font_variant();
|
||||
switch (font_variant) {
|
||||
|
|
|
@ -2036,7 +2036,7 @@ Length::FontMetrics StyleComputer::calculate_root_element_font_metrics(StyleProp
|
|||
auto root_value = style.property(CSS::PropertyID::FontSize);
|
||||
|
||||
auto font_pixel_metrics = style.computed_font().pixel_metrics();
|
||||
Length::FontMetrics font_metrics { m_default_font_metrics.font_size, font_pixel_metrics, CSSPixels(font_pixel_metrics.line_spacing()) };
|
||||
Length::FontMetrics font_metrics { m_default_font_metrics.font_size, font_pixel_metrics, CSSPixels::nearest_value_for(font_pixel_metrics.line_spacing()) };
|
||||
font_metrics.font_size = root_value->as_length().length().to_px(viewport_rect(), font_metrics, font_metrics);
|
||||
font_metrics.line_height = style.line_height(viewport_rect(), font_metrics, font_metrics);
|
||||
|
||||
|
@ -2197,7 +2197,7 @@ RefPtr<Gfx::Font const> StyleComputer::compute_font_for_style_values(DOM::Elemen
|
|||
// and smaller may compute the font size to the previous entry in the table.
|
||||
if (identifier == CSS::ValueID::Smaller || identifier == CSS::ValueID::Larger) {
|
||||
if (parent_element && parent_element->computed_css_values()) {
|
||||
font_size_in_px = CSSPixels(parent_element->computed_css_values()->computed_font().pixel_metrics().size);
|
||||
font_size_in_px = CSSPixels::nearest_value_for(parent_element->computed_css_values()->computed_font().pixel_metrics().size);
|
||||
}
|
||||
}
|
||||
auto const multiplier = absolute_size_mapping.get(identifier).value_or(1.0);
|
||||
|
@ -2213,7 +2213,7 @@ RefPtr<Gfx::Font const> StyleComputer::compute_font_for_style_values(DOM::Elemen
|
|||
Optional<Length> maybe_length;
|
||||
if (font_size.is_percentage()) {
|
||||
// Percentages refer to parent element's font size
|
||||
maybe_length = Length::make_px(CSSPixels(font_size.as_percentage().percentage().as_fraction() * parent_font_size().to_double()));
|
||||
maybe_length = Length::make_px(CSSPixels::nearest_value_for(font_size.as_percentage().percentage().as_fraction() * parent_font_size().to_double()));
|
||||
|
||||
} else if (font_size.is_length()) {
|
||||
maybe_length = font_size.as_length().length();
|
||||
|
@ -2350,7 +2350,7 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
|
|||
|
||||
auto found_font = compute_font_for_style_values(element, pseudo_element, font_family, font_size, font_style, font_weight, font_stretch);
|
||||
|
||||
style.set_property(CSS::PropertyID::FontSize, LengthStyleValue::create(CSS::Length::make_px(CSSPixels(found_font->pixel_size()))), nullptr);
|
||||
style.set_property(CSS::PropertyID::FontSize, LengthStyleValue::create(CSS::Length::make_px(CSSPixels::nearest_value_for(found_font->pixel_size()))), nullptr);
|
||||
style.set_property(CSS::PropertyID::FontWeight, NumberStyleValue::create(font_weight->to_font_weight()));
|
||||
|
||||
style.set_computed_font(found_font.release_nonnull());
|
||||
|
@ -2401,7 +2401,7 @@ void StyleComputer::absolutize_values(StyleProperties& style, DOM::Element const
|
|||
auto line_height_value_slot = style.m_property_values[to_underlying(CSS::PropertyID::LineHeight)].map([](auto& x) -> auto& { return x.style; });
|
||||
if (line_height_value_slot.has_value() && (*line_height_value_slot)->is_percentage()) {
|
||||
*line_height_value_slot = LengthStyleValue::create(
|
||||
Length::make_px(CSSPixels(font_size * static_cast<double>((*line_height_value_slot)->as_percentage().percentage().as_fraction()))));
|
||||
Length::make_px(CSSPixels::nearest_value_for(font_size * static_cast<double>((*line_height_value_slot)->as_percentage().percentage().as_fraction()))));
|
||||
}
|
||||
|
||||
auto line_height = style.line_height(viewport_rect(), font_metrics, m_root_element_font_metrics);
|
||||
|
|
|
@ -204,7 +204,7 @@ CSSPixels StyleProperties::line_height(Layout::Node const& layout_node) const
|
|||
auto line_height = property(CSS::PropertyID::LineHeight);
|
||||
|
||||
if (line_height->is_identifier() && line_height->to_identifier() == ValueID::Normal)
|
||||
return CSSPixels(layout_node.font().pixel_metrics().line_spacing());
|
||||
return CSSPixels::nearest_value_for(layout_node.font().pixel_metrics().line_spacing());
|
||||
|
||||
if (line_height->is_length()) {
|
||||
auto line_height_length = line_height->as_length().length();
|
||||
|
@ -226,7 +226,7 @@ CSSPixels StyleProperties::line_height(Layout::Node const& layout_node) const
|
|||
auto resolved = line_height->as_calculated().resolve_number();
|
||||
if (!resolved.has_value()) {
|
||||
dbgln("FIXME: Failed to resolve calc() line-height (number): {}", line_height->as_calculated().to_string());
|
||||
return CSSPixels(layout_node.font().pixel_metrics().line_spacing());
|
||||
return CSSPixels::nearest_value_for(layout_node.font().pixel_metrics().line_spacing());
|
||||
}
|
||||
return Length(resolved.value(), Length::Type::Em).to_px(layout_node);
|
||||
}
|
||||
|
@ -234,12 +234,12 @@ CSSPixels StyleProperties::line_height(Layout::Node const& layout_node) const
|
|||
auto resolved = line_height->as_calculated().resolve_length(layout_node);
|
||||
if (!resolved.has_value()) {
|
||||
dbgln("FIXME: Failed to resolve calc() line-height: {}", line_height->as_calculated().to_string());
|
||||
return CSSPixels(layout_node.font().pixel_metrics().line_spacing());
|
||||
return CSSPixels::nearest_value_for(layout_node.font().pixel_metrics().line_spacing());
|
||||
}
|
||||
return resolved->to_px(layout_node);
|
||||
}
|
||||
|
||||
return CSSPixels(layout_node.font().pixel_metrics().line_spacing());
|
||||
return CSSPixels::nearest_value_for(layout_node.font().pixel_metrics().line_spacing());
|
||||
}
|
||||
|
||||
Optional<int> StyleProperties::z_index() const
|
||||
|
|
|
@ -77,7 +77,7 @@ static CalculatedStyleValue::CalculationResult to_resolved_type(CalculatedStyleV
|
|||
case CalculatedStyleValue::ResolvedType::Frequency:
|
||||
return { Frequency::make_hertz(value) };
|
||||
case CalculatedStyleValue::ResolvedType::Length:
|
||||
return { Length::make_px(CSSPixels(value)) };
|
||||
return { Length::make_px(CSSPixels::nearest_value_for(value)) };
|
||||
case CalculatedStyleValue::ResolvedType::Percentage:
|
||||
return { Percentage(value) };
|
||||
case CalculatedStyleValue::ResolvedType::Time:
|
||||
|
@ -2155,7 +2155,7 @@ void CalculatedStyleValue::CalculationResult::multiply_by(CalculationResult cons
|
|||
m_value = Frequency::make_hertz(frequency.to_hertz() * other.m_value.get<Number>().value());
|
||||
},
|
||||
[&](Length const& length) {
|
||||
m_value = Length::make_px(CSSPixels(length.to_px(*context) * static_cast<double>(other.m_value.get<Number>().value())));
|
||||
m_value = Length::make_px(CSSPixels::nearest_value_for(length.to_px(*context) * static_cast<double>(other.m_value.get<Number>().value())));
|
||||
},
|
||||
[&](Time const& time) {
|
||||
m_value = Time::make_seconds(time.to_seconds() * other.m_value.get<Number>().value());
|
||||
|
@ -2187,7 +2187,7 @@ void CalculatedStyleValue::CalculationResult::divide_by(CalculationResult const&
|
|||
m_value = Frequency::make_hertz(frequency.to_hertz() / denominator);
|
||||
},
|
||||
[&](Length const& length) {
|
||||
m_value = Length::make_px(CSSPixels(length.to_px(*context) / static_cast<double>(denominator)));
|
||||
m_value = Length::make_px(CSSPixels::nearest_value_for(length.to_px(*context) / static_cast<double>(denominator)));
|
||||
},
|
||||
[&](Time const& time) {
|
||||
m_value = Time::make_seconds(time.to_seconds() / denominator);
|
||||
|
|
|
@ -150,8 +150,8 @@ Gfx::FloatSize RadialGradientStyleValue::resolve_size(Layout::Node const& node,
|
|||
return Gfx::FloatSize { radius.to_float(), radius.to_float() };
|
||||
},
|
||||
[&](EllipseSize const& ellipse_size) {
|
||||
auto radius_a = ellipse_size.radius_a.resolved(node, CSS::Length::make_px(CSSPixels(size.width()))).to_px(node);
|
||||
auto radius_b = ellipse_size.radius_b.resolved(node, CSS::Length::make_px(CSSPixels(size.height()))).to_px(node);
|
||||
auto radius_a = ellipse_size.radius_a.resolved(node, CSS::Length::make_px(CSSPixels::nearest_value_for(size.width()))).to_px(node);
|
||||
auto radius_b = ellipse_size.radius_b.resolved(node, CSS::Length::make_px(CSSPixels::nearest_value_for(size.height()))).to_px(node);
|
||||
return Gfx::FloatSize { radius_a.to_float(), radius_b.to_float() };
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue