mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
LibWeb: Remove implicit conversion from float and double to CSSPixels
In general it is not safe to convert any arbitrary floating-point value to CSSPixels. CSSPixels has a resolution of 0.015625, which for small values (e.g. scale factors between 0 and 1), can produce bad results if converted to CSSPixels then scaled back up. In the worst case values can underflow to zero and produce incorrect results.
This commit is contained in:
parent
0f9c088302
commit
360c0eb509
Notes:
sideshowbarker
2024-07-17 10:10:18 +09:00
Author: https://github.com/MacDue Commit: https://github.com/SerenityOS/serenity/commit/360c0eb509 Pull-request: https://github.com/SerenityOS/serenity/pull/20789
43 changed files with 248 additions and 221 deletions
|
@ -2,37 +2,37 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
|||
BlockContainer <html> at (0,0) content-size 800x616 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x600 children: not-inline
|
||||
Box <div.outer.row> at (8,8) content-size 150x150 flex-container(row) [FFC] children: not-inline
|
||||
BlockContainer <div.inner> at (12.625,8) content-size 30.078125x150 flex-item [BFC] children: inline
|
||||
BlockContainer <div.inner> at (12.609375,8) content-size 30.078125x150 flex-item [BFC] children: inline
|
||||
line 0 width: 30.078125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 4, rect: [12.625,8 30.078125x17.46875]
|
||||
frag 0 from TextNode start: 0, length: 4, rect: [12.609375,8 30.078125x17.46875]
|
||||
"Well"
|
||||
TextNode <#text>
|
||||
BlockContainer <div.inner> at (51.9375,8) content-size 36.84375x150 flex-item [BFC] children: inline
|
||||
BlockContainer <div.inner> at (51.921875,8) content-size 36.84375x150 flex-item [BFC] children: inline
|
||||
line 0 width: 36.84375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 5, rect: [51.9375,8 36.84375x17.46875]
|
||||
frag 0 from TextNode start: 0, length: 5, rect: [51.921875,8 36.84375x17.46875]
|
||||
"hello"
|
||||
TextNode <#text>
|
||||
BlockContainer <div.inner> at (98.015625,8) content-size 55.359375x150 flex-item [BFC] children: inline
|
||||
BlockContainer <div.inner> at (98,8) content-size 55.359375x150 flex-item [BFC] children: inline
|
||||
line 0 width: 55.359375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 7, rect: [98.015625,8 55.359375x17.46875]
|
||||
frag 0 from TextNode start: 0, length: 7, rect: [98,8 55.359375x17.46875]
|
||||
"friends"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,158) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
Box <div.outer.row-reverse> at (8,158) content-size 150x150 flex-container(row-reverse) [FFC] children: not-inline
|
||||
BlockContainer <div.inner> at (123.296875,158) content-size 30.078125x150 flex-item [BFC] children: inline
|
||||
BlockContainer <div.inner> at (123.3125,158) content-size 30.078125x150 flex-item [BFC] children: inline
|
||||
line 0 width: 30.078125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 4, rect: [123.296875,158 30.078125x17.46875]
|
||||
frag 0 from TextNode start: 0, length: 4, rect: [123.3125,158 30.078125x17.46875]
|
||||
"Well"
|
||||
TextNode <#text>
|
||||
BlockContainer <div.inner> at (77.21875,158) content-size 36.84375x150 flex-item [BFC] children: inline
|
||||
BlockContainer <div.inner> at (77.234375,158) content-size 36.84375x150 flex-item [BFC] children: inline
|
||||
line 0 width: 36.84375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 5, rect: [77.21875,158 36.84375x17.46875]
|
||||
frag 0 from TextNode start: 0, length: 5, rect: [77.234375,158 36.84375x17.46875]
|
||||
"hello"
|
||||
TextNode <#text>
|
||||
BlockContainer <div.inner> at (12.625,158) content-size 55.359375x150 flex-item [BFC] children: inline
|
||||
BlockContainer <div.inner> at (12.640625,158) content-size 55.359375x150 flex-item [BFC] children: inline
|
||||
line 0 width: 55.359375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 7, rect: [12.625,158 55.359375x17.46875]
|
||||
frag 0 from TextNode start: 0, length: 7, rect: [12.640625,158 55.359375x17.46875]
|
||||
"friends"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,308) content-size 784x0 children: inline
|
||||
|
@ -76,19 +76,19 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600] overflow: [0,0 800x616]
|
|||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x616]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x600]
|
||||
PaintableBox (Box<DIV>.outer.row) [8,8 150x150]
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [12.625,8 30.078125x150]
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [12.609375,8 30.078125x150]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [51.9375,8 36.84375x150]
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [51.921875,8 36.84375x150]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [98.015625,8 55.359375x150]
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [98,8 55.359375x150]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer(anonymous)) [8,158 784x0]
|
||||
PaintableBox (Box<DIV>.outer.row-reverse) [8,158 150x150]
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [123.296875,158 30.078125x150]
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [123.3125,158 30.078125x150]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [77.21875,158 36.84375x150]
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [77.234375,158 36.84375x150]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [12.625,158 55.359375x150]
|
||||
PaintableWithLines (BlockContainer<DIV>.inner) [12.640625,158 55.359375x150]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer(anonymous)) [8,308 784x0]
|
||||
PaintableBox (Box<DIV>.outer.column) [8,308 150x150]
|
||||
|
|
|
@ -2,9 +2,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
|||
BlockContainer <html> at (1,1) content-size 798x37.46875 [BFC] children: not-inline
|
||||
BlockContainer <body> at (10,10) content-size 780x19.46875 children: not-inline
|
||||
Box <div.container> at (11,11) content-size 800x17.46875 flex-container(row) [FFC] children: not-inline
|
||||
BlockContainer <(anonymous)> at (392.21875,11) content-size 37.578125x17.46875 flex-item [BFC] children: inline
|
||||
BlockContainer <(anonymous)> at (392.203125,11) content-size 37.578125x17.46875 flex-item [BFC] children: inline
|
||||
line 0 width: 37.578125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 4, rect: [392.21875,11 37.578125x17.46875]
|
||||
frag 0 from TextNode start: 0, length: 4, rect: [392.203125,11 37.578125x17.46875]
|
||||
"Text"
|
||||
TextNode <#text>
|
||||
|
||||
|
@ -12,5 +12,5 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600] overflow: [0,0 812x600]
|
|||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x39.46875] overflow: [1,1 811x37.46875]
|
||||
PaintableWithLines (BlockContainer<BODY>) [9,9 782x21.46875] overflow: [10,10 802x19.46875]
|
||||
PaintableBox (Box<DIV>.container) [10,10 802x19.46875]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [392.21875,11 37.578125x17.46875]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [392.203125,11 37.578125x17.46875]
|
||||
TextPaintable (TextNode<#text>)
|
||||
|
|
|
@ -33,7 +33,7 @@ TEST_CASE(division1)
|
|||
EXPECT_EQ(c, CSSPixels(2));
|
||||
|
||||
a = CSSPixels::from_raw(0x3FFF'FFFF); // int_max / 2
|
||||
b = 0.25;
|
||||
b = CSSPixels(0.25);
|
||||
EXPECT(!a.might_be_saturated());
|
||||
EXPECT((a / b).might_be_saturated());
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eu ante est. Integer ipsum sem, tincidunt quis felis quis, efficitur fringilla neque. Aliquam erat volutpat. Donec feugiat euismod sapien. Donec vel egestas arcu. Suspendisse luctus rhoncus mi quis elementum. Maecenas vel nisi maximus, viverra tellus quis, ultrices elit. Quisque congue velit quis lectus congue, ut consectetur nulla pharetra. Nullam euismod leo eget magna auctor, et bibendum urna tincidunt. Morbi molestie gravida ex ac consectetur. Duis pretium gravida augue eu sagittis. 193
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eu ante est. Integer ipsum sem, tincidunt quis felis quis, efficitur fringilla neque. Aliquam erat volutpat. Donec feugiat euismod sapien. Donec vel egestas arcu. Suspendisse luctus rhoncus mi quis elementum. Maecenas vel nisi maximus, viverra tellus quis, ultrices elit. Quisque congue velit quis lectus congue, ut consectetur nulla pharetra. Nullam euismod leo eget magna auctor, et bibendum urna tincidunt. Morbi molestie gravida ex ac consectetur. Duis pretium gravida augue eu sagittis. 192
|
||||
|
|
|
@ -185,18 +185,18 @@ void InspectorWidget::update_node_box_model(StringView node_box_sizing_json)
|
|||
auto json_value = json_or_error.release_value();
|
||||
auto const& json_object = json_value.as_object();
|
||||
|
||||
m_node_box_sizing.margin.top = json_object.get_float("margin_top"sv).value_or(0);
|
||||
m_node_box_sizing.margin.right = json_object.get_float("margin_right"sv).value_or(0);
|
||||
m_node_box_sizing.margin.bottom = json_object.get_float("margin_bottom"sv).value_or(0);
|
||||
m_node_box_sizing.margin.left = json_object.get_float("margin_left"sv).value_or(0);
|
||||
m_node_box_sizing.padding.top = json_object.get_float("padding_top"sv).value_or(0);
|
||||
m_node_box_sizing.padding.right = json_object.get_float("padding_right"sv).value_or(0);
|
||||
m_node_box_sizing.padding.bottom = json_object.get_float("padding_bottom"sv).value_or(0);
|
||||
m_node_box_sizing.padding.left = json_object.get_float("padding_left"sv).value_or(0);
|
||||
m_node_box_sizing.border.top = json_object.get_float("border_top"sv).value_or(0);
|
||||
m_node_box_sizing.border.right = json_object.get_float("border_right"sv).value_or(0);
|
||||
m_node_box_sizing.border.bottom = json_object.get_float("border_bottom"sv).value_or(0);
|
||||
m_node_box_sizing.border.left = json_object.get_float("border_left"sv).value_or(0);
|
||||
m_node_box_sizing.margin.top = Web::CSSPixels(json_object.get_float("margin_top"sv).value_or(0));
|
||||
m_node_box_sizing.margin.right = Web::CSSPixels(json_object.get_float("margin_right"sv).value_or(0));
|
||||
m_node_box_sizing.margin.bottom = Web::CSSPixels(json_object.get_float("margin_bottom"sv).value_or(0));
|
||||
m_node_box_sizing.margin.left = Web::CSSPixels(json_object.get_float("margin_left"sv).value_or(0));
|
||||
m_node_box_sizing.padding.top = Web::CSSPixels(json_object.get_float("padding_top"sv).value_or(0));
|
||||
m_node_box_sizing.padding.right = Web::CSSPixels(json_object.get_float("padding_right"sv).value_or(0));
|
||||
m_node_box_sizing.padding.bottom = Web::CSSPixels(json_object.get_float("padding_bottom"sv).value_or(0));
|
||||
m_node_box_sizing.padding.left = Web::CSSPixels(json_object.get_float("padding_left"sv).value_or(0));
|
||||
m_node_box_sizing.border.top = Web::CSSPixels(json_object.get_float("border_top"sv).value_or(0));
|
||||
m_node_box_sizing.border.right = Web::CSSPixels(json_object.get_float("border_right"sv).value_or(0));
|
||||
m_node_box_sizing.border.bottom = Web::CSSPixels(json_object.get_float("border_bottom"sv).value_or(0));
|
||||
m_node_box_sizing.border.left = Web::CSSPixels(json_object.get_float("border_left"sv).value_or(0));
|
||||
|
||||
m_element_size_view->set_node_content_width(json_object.get_float("content_width"sv).value_or(0));
|
||||
m_element_size_view->set_node_content_height(json_object.get_float("content_height"sv).value_or(0));
|
||||
|
|
|
@ -24,10 +24,10 @@ Gfx::FloatRect EdgeRect::resolved(Layout::Node const& layout_node, Gfx::Rect<dou
|
|||
// widths for <bottom>, and the same as the used value of the width plus the sum of the
|
||||
// horizontal padding and border widths for <right>, such that four 'auto' values result in the
|
||||
// clipping region being the same as the element's border box).
|
||||
auto left = border_box.left() + (left_edge.is_auto() ? 0 : left_edge.to_px(layout_node)).to_double();
|
||||
auto top = border_box.top() + (top_edge.is_auto() ? 0 : top_edge.to_px(layout_node)).to_double();
|
||||
auto right = border_box.left() + (right_edge.is_auto() ? border_box.width() : right_edge.to_px(layout_node)).to_double();
|
||||
auto bottom = border_box.top() + (bottom_edge.is_auto() ? border_box.height() : bottom_edge.to_px(layout_node)).to_double();
|
||||
auto left = border_box.left() + (left_edge.is_auto() ? 0 : left_edge.to_px(layout_node).to_double());
|
||||
auto top = border_box.top() + (top_edge.is_auto() ? 0 : top_edge.to_px(layout_node).to_double());
|
||||
auto right = border_box.left() + (right_edge.is_auto() ? border_box.width() : right_edge.to_px(layout_node).to_double());
|
||||
auto bottom = border_box.top() + (bottom_edge.is_auto() ? border_box.height() : bottom_edge.to_px(layout_node).to_double());
|
||||
return Gfx::FloatRect {
|
||||
left,
|
||||
top,
|
||||
|
|
|
@ -61,31 +61,31 @@ CSSPixels Length::font_relative_length_to_px(Length::FontMetrics const& font_met
|
|||
{
|
||||
switch (m_type) {
|
||||
case Type::Em:
|
||||
return m_value * font_metrics.font_size.to_double();
|
||||
return CSSPixels(m_value * font_metrics.font_size.to_double());
|
||||
case Type::Rem:
|
||||
return m_value * root_font_metrics.font_size.to_double();
|
||||
return CSSPixels(m_value * root_font_metrics.font_size.to_double());
|
||||
case Type::Ex:
|
||||
return m_value * font_metrics.x_height.to_double();
|
||||
return CSSPixels(m_value * font_metrics.x_height.to_double());
|
||||
case Type::Rex:
|
||||
return m_value * root_font_metrics.x_height.to_double();
|
||||
return CSSPixels(m_value * root_font_metrics.x_height.to_double());
|
||||
case Type::Cap:
|
||||
return m_value * font_metrics.cap_height.to_double();
|
||||
return CSSPixels(m_value * font_metrics.cap_height.to_double());
|
||||
case Type::Rcap:
|
||||
return m_value * root_font_metrics.cap_height.to_double();
|
||||
return CSSPixels(m_value * root_font_metrics.cap_height.to_double());
|
||||
case Type::Ch:
|
||||
return m_value * font_metrics.zero_advance.to_double();
|
||||
return CSSPixels(m_value * font_metrics.zero_advance.to_double());
|
||||
case Type::Rch:
|
||||
return m_value * root_font_metrics.zero_advance.to_double();
|
||||
return CSSPixels(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 m_value * font_metrics.font_size.to_double();
|
||||
return CSSPixels(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 m_value * root_font_metrics.font_size.to_double();
|
||||
return CSSPixels(m_value * root_font_metrics.font_size.to_double());
|
||||
case Type::Lh:
|
||||
return m_value * font_metrics.line_height.to_double();
|
||||
return CSSPixels(m_value * font_metrics.line_height.to_double());
|
||||
case Type::Rlh:
|
||||
return m_value * root_font_metrics.line_height.to_double();
|
||||
return CSSPixels(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 viewport_rect.width() * (m_value / 100);
|
||||
return CSSPixels(viewport_rect.width() * (m_value / 100));
|
||||
case Type::Vh:
|
||||
case Type::Svh:
|
||||
case Type::Lvh:
|
||||
case Type::Dvh:
|
||||
return viewport_rect.height() * (m_value / 100);
|
||||
return CSSPixels(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 viewport_rect.width() * (m_value / 100);
|
||||
return CSSPixels(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 viewport_rect.height() * (m_value / 100);
|
||||
return CSSPixels(viewport_rect.height() * (m_value / 100));
|
||||
case Type::Vmin:
|
||||
case Type::Svmin:
|
||||
case Type::Lvmin:
|
||||
case Type::Dvmin:
|
||||
return min(viewport_rect.width(), viewport_rect.height()) * (m_value / 100);
|
||||
return CSSPixels(min(viewport_rect.width(), viewport_rect.height()) * (m_value / 100));
|
||||
case Type::Vmax:
|
||||
case Type::Svmax:
|
||||
case Type::Lvmax:
|
||||
case Type::Dvmax:
|
||||
return max(viewport_rect.width(), viewport_rect.height()) * (m_value / 100);
|
||||
return CSSPixels(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 = { node.computed_values().font_size(), node.font().pixel_metrics(), node.line_height() },
|
||||
.root_font_metrics = { root_element->layout_node()->computed_values().font_size(), root_element->layout_node()->font().pixel_metrics(), root_element->layout_node()->line_height() },
|
||||
.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() },
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -168,12 +168,12 @@ CSSPixels Length::to_px(Layout::Node const& layout_node) const
|
|||
return 0;
|
||||
|
||||
FontMetrics font_metrics {
|
||||
layout_node.computed_values().font_size(),
|
||||
CSSPixels(layout_node.computed_values().font_size()),
|
||||
layout_node.font().pixel_metrics(),
|
||||
layout_node.line_height()
|
||||
};
|
||||
FontMetrics root_font_metrics {
|
||||
root_element->layout_node()->computed_values().font_size(),
|
||||
CSSPixels(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 m_value * centimeter_pixels; // 1cm = 96px/2.54
|
||||
return CSSPixels(m_value * centimeter_pixels); // 1cm = 96px/2.54
|
||||
case Type::In:
|
||||
return m_value * inch_pixels; // 1in = 2.54 cm = 96px
|
||||
return CSSPixels(m_value * inch_pixels); // 1in = 2.54 cm = 96px
|
||||
case Type::Px:
|
||||
return m_value; // 1px = 1/96th of 1in
|
||||
return CSSPixels(m_value); // 1px = 1/96th of 1in
|
||||
case Type::Pt:
|
||||
return m_value * ((1.0 / 72.0) * inch_pixels); // 1pt = 1/72th of 1in
|
||||
return CSSPixels(m_value * ((1.0 / 72.0) * inch_pixels)); // 1pt = 1/72th of 1in
|
||||
case Type::Pc:
|
||||
return m_value * ((1.0 / 6.0) * inch_pixels); // 1pc = 1/6th of 1in
|
||||
return CSSPixels(m_value * ((1.0 / 6.0) * inch_pixels)); // 1pc = 1/6th of 1in
|
||||
case Type::Mm:
|
||||
return m_value * ((1.0 / 10.0) * centimeter_pixels); // 1mm = 1/10th of 1cm
|
||||
return CSSPixels(m_value * ((1.0 / 10.0) * centimeter_pixels)); // 1mm = 1/10th of 1cm
|
||||
case Type::Q:
|
||||
return m_value * ((1.0 / 40.0) * centimeter_pixels); // 1Q = 1/40th of 1cm
|
||||
return CSSPixels(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 { static_cast<CSSPixels>(initial_font.presentation_size()), initial_font_metrics, initial_font_metrics.line_spacing() };
|
||||
Length::FontMetrics font_metrics { CSSPixels(initial_font.presentation_size()), initial_font_metrics, CSSPixels(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(numeric_value);
|
||||
return Length::make_px(CSSPixels(numeric_value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@ CSSPixelPoint PositionValue::resolved(Layout::Node const& node, CSSPixelRect con
|
|||
return rect.width() * [&] {
|
||||
switch (preset) {
|
||||
case HorizontalPreset::Left:
|
||||
return 0.;
|
||||
return CSSPixels(0.0);
|
||||
case HorizontalPreset::Center:
|
||||
return 0.5;
|
||||
return CSSPixels(0.5);
|
||||
case HorizontalPreset::Right:
|
||||
return 1.;
|
||||
return CSSPixels(1.0);
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
@ -36,11 +36,11 @@ CSSPixelPoint PositionValue::resolved(Layout::Node const& node, CSSPixelRect con
|
|||
return rect.height() * [&] {
|
||||
switch (preset) {
|
||||
case VerticalPreset::Top:
|
||||
return 0.;
|
||||
return CSSPixels(0.0);
|
||||
case VerticalPreset::Center:
|
||||
return 0.5;
|
||||
return CSSPixels(0.5);
|
||||
case VerticalPreset::Bottom:
|
||||
return 1.;
|
||||
return CSSPixels(1.0);
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
|
|
@ -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(layout_node.computed_values().font_size()));
|
||||
return LengthStyleValue::create(Length::make_px(CSSPixels(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, font_pixel_metrics.line_spacing() };
|
||||
Length::FontMetrics font_metrics { m_default_font_metrics.font_size, font_pixel_metrics, CSSPixels(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);
|
||||
|
||||
|
@ -2150,7 +2150,7 @@ RefPtr<Gfx::Font const> StyleComputer::compute_font_for_style_values(DOM::Elemen
|
|||
bool bold = weight > Gfx::FontWeight::Regular;
|
||||
|
||||
// FIXME: Should be based on "user's default font size"
|
||||
float font_size_in_px = 16;
|
||||
CSSPixels font_size_in_px = 16;
|
||||
|
||||
auto parent_line_height = parent_or_root_element_line_height(element, pseudo_element);
|
||||
Gfx::FontPixelMetrics font_pixel_metrics;
|
||||
|
@ -2197,11 +2197,11 @@ 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 = parent_element->computed_css_values()->computed_font().pixel_metrics().size;
|
||||
font_size_in_px = CSSPixels(parent_element->computed_css_values()->computed_font().pixel_metrics().size);
|
||||
}
|
||||
}
|
||||
auto const multiplier = absolute_size_mapping.get(identifier).value_or(1.0);
|
||||
font_size_in_px *= multiplier;
|
||||
font_size_in_px.scale_by(multiplier);
|
||||
|
||||
} else {
|
||||
Length::ResolutionContext const length_resolution_context {
|
||||
|
@ -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(font_size.as_percentage().percentage().as_fraction() * parent_font_size().to_double());
|
||||
maybe_length = Length::make_px(CSSPixels(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(found_font->pixel_size())), nullptr);
|
||||
style.set_property(CSS::PropertyID::FontSize, LengthStyleValue::create(CSS::Length::make_px(CSSPixels(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(font_size * static_cast<double>((*line_height_value_slot)->as_percentage().percentage().as_fraction())));
|
||||
Length::make_px(CSSPixels(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 layout_node.font().pixel_metrics().line_spacing();
|
||||
return CSSPixels(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 layout_node.font().pixel_metrics().line_spacing();
|
||||
return CSSPixels(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 layout_node.font().pixel_metrics().line_spacing();
|
||||
return CSSPixels(layout_node.font().pixel_metrics().line_spacing());
|
||||
}
|
||||
return resolved->to_px(layout_node);
|
||||
}
|
||||
|
||||
return layout_node.font().pixel_metrics().line_spacing();
|
||||
return CSSPixels(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(value) };
|
||||
return { Length::make_px(CSSPixels(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(length.to_px(*context) * static_cast<double>(other.m_value.get<Number>().value()));
|
||||
m_value = Length::make_px(CSSPixels(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(length.to_px(*context) / static_cast<double>(denominator));
|
||||
m_value = Length::make_px(CSSPixels(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(size.width())).to_px(node);
|
||||
auto radius_b = ellipse_size.radius_b.resolved(node, CSS::Length::make_px(size.height())).to_px(node);
|
||||
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);
|
||||
return Gfx::FloatSize { radius_a.to_float(), radius_b.to_float() };
|
||||
});
|
||||
|
||||
|
|
|
@ -1085,7 +1085,7 @@ void Element::set_scroll_left(double x)
|
|||
// 11. Scroll the element to x,scrollTop, with the scroll behavior being "auto".
|
||||
// FIXME: Implement this in terms of calling "scroll the element".
|
||||
auto scroll_offset = paintable_box()->scroll_offset();
|
||||
scroll_offset.set_x(static_cast<float>(x));
|
||||
scroll_offset.set_x(CSSPixels(x));
|
||||
paintable_box()->set_scroll_offset(scroll_offset);
|
||||
}
|
||||
|
||||
|
@ -1153,7 +1153,7 @@ void Element::set_scroll_top(double y)
|
|||
// 11. Scroll the element to scrollLeft,y, with the scroll behavior being "auto".
|
||||
// FIXME: Implement this in terms of calling "scroll the element".
|
||||
auto scroll_offset = paintable_box()->scroll_offset();
|
||||
scroll_offset.set_y(static_cast<float>(y));
|
||||
scroll_offset.set_y(CSSPixels(y));
|
||||
paintable_box()->set_scroll_offset(scroll_offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -3993,14 +3993,14 @@ static RefPtr<CSS::StyleValue> parse_current_dimension_value(float value, Utf8Vi
|
|||
{
|
||||
// 1. If position is past the end of input, then return value as a length.
|
||||
if (position == input.end())
|
||||
return CSS::LengthStyleValue::create(CSS::Length::make_px(value));
|
||||
return CSS::LengthStyleValue::create(CSS::Length::make_px(CSSPixels(value)));
|
||||
|
||||
// 2. If the code point at position within input is U+0025 (%), then return value as a percentage.
|
||||
if (*position == '%')
|
||||
return CSS::PercentageStyleValue::create(CSS::Percentage(value));
|
||||
|
||||
// 3. Return value as a length.
|
||||
return CSS::LengthStyleValue::create(CSS::Length::make_px(value));
|
||||
return CSS::LengthStyleValue::create(CSS::Length::make_px(CSSPixels(value)));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-dimension-values
|
||||
|
@ -4065,7 +4065,7 @@ RefPtr<CSS::StyleValue> parse_dimension_value(StringView string)
|
|||
|
||||
// 4. If position is past the end of input, then return value as a length.
|
||||
if (position == input.end())
|
||||
return CSS::LengthStyleValue::create(CSS::Length::make_px(value));
|
||||
return CSS::LengthStyleValue::create(CSS::Length::make_px(CSSPixels(value)));
|
||||
|
||||
// 5. If the code point at position within input is not an ASCII digit, then break.
|
||||
if (!is_ascii_digit(*position))
|
||||
|
|
|
@ -481,12 +481,12 @@ Optional<CSS::MediaFeatureValue> Window::query_media_feature(CSS::MediaFeatureID
|
|||
// FIXME: device-aspect-ratio
|
||||
case CSS::MediaFeatureID::DeviceHeight:
|
||||
if (auto* page = this->page()) {
|
||||
return CSS::MediaFeatureValue(CSS::Length::make_px(page->web_exposed_screen_area().height().to_double()));
|
||||
return CSS::MediaFeatureValue(CSS::Length::make_px(page->web_exposed_screen_area().height()));
|
||||
}
|
||||
return CSS::MediaFeatureValue(0);
|
||||
case CSS::MediaFeatureID::DeviceWidth:
|
||||
if (auto* page = this->page()) {
|
||||
return CSS::MediaFeatureValue(CSS::Length::make_px(page->web_exposed_screen_area().width().to_double()));
|
||||
return CSS::MediaFeatureValue(CSS::Length::make_px(page->web_exposed_screen_area().width()));
|
||||
}
|
||||
return CSS::MediaFeatureValue(0);
|
||||
case CSS::MediaFeatureID::DisplayMode:
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
CSSPixels to_px_or_zero() const
|
||||
{
|
||||
if (!is_definite())
|
||||
return 0.0f;
|
||||
return 0;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
|
|
|
@ -1069,7 +1069,7 @@ void BlockFormattingContext::layout_list_item_marker(ListItemBox const& list_ite
|
|||
marker_state.set_content_width(image_width + default_marker_width);
|
||||
} else {
|
||||
auto text_width = marker.font().width(marker.text());
|
||||
marker_state.set_content_width(image_width + text_width);
|
||||
marker_state.set_content_width(image_width + CSSPixels(text_width));
|
||||
}
|
||||
|
||||
marker_state.set_content_height(max(image_height, marker.font().pixel_size_rounded_up() + 1));
|
||||
|
|
|
@ -25,7 +25,7 @@ void ButtonBox::prepare_for_replaced_layout()
|
|||
// value attribute. This is not the case with <button />, which contains
|
||||
// its contents normally.
|
||||
if (is<HTML::HTMLInputElement>(dom_node())) {
|
||||
set_natural_width(font().width(static_cast<HTML::HTMLInputElement&>(dom_node()).value()));
|
||||
set_natural_width(CSSPixels(font().width(static_cast<HTML::HTMLInputElement&>(dom_node()).value())));
|
||||
set_natural_height(font().pixel_size_rounded_up());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -540,15 +540,15 @@ CSS::FlexBasis FlexFormattingContext::used_flex_basis_for_item(FlexItem const& i
|
|||
CSSPixels FlexFormattingContext::calculate_main_size_from_cross_size_and_aspect_ratio(CSSPixels cross_size, double aspect_ratio) const
|
||||
{
|
||||
if (is_row_layout())
|
||||
return cross_size * aspect_ratio;
|
||||
return cross_size / aspect_ratio;
|
||||
return CSSPixels(cross_size * aspect_ratio);
|
||||
return CSSPixels(cross_size / aspect_ratio);
|
||||
}
|
||||
|
||||
CSSPixels FlexFormattingContext::calculate_cross_size_from_main_size_and_aspect_ratio(CSSPixels main_size, double aspect_ratio) const
|
||||
{
|
||||
if (is_row_layout())
|
||||
return main_size / aspect_ratio;
|
||||
return main_size * aspect_ratio;
|
||||
return CSSPixels(main_size / aspect_ratio);
|
||||
return CSSPixels(main_size * aspect_ratio);
|
||||
}
|
||||
|
||||
// This function takes a size in the main axis and adjusts it according to the aspect ratio of the box
|
||||
|
@ -687,7 +687,7 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size(
|
|||
|
||||
// The hypothetical main size is the item’s flex base size clamped according to its used min and max main sizes (and flooring the content box size at zero).
|
||||
auto clamp_min = has_main_min_size(child_box) ? specified_main_min_size(child_box) : automatic_minimum_size(item);
|
||||
auto clamp_max = has_main_max_size(child_box) ? specified_main_max_size(child_box) : NumericLimits<float>::max();
|
||||
auto clamp_max = has_main_max_size(child_box) ? specified_main_max_size(child_box) : CSSPixels::max();
|
||||
item.hypothetical_main_size = max(CSSPixels(0), css_clamp(item.flex_base_size, clamp_min, clamp_max));
|
||||
|
||||
// NOTE: At this point, we set the hypothetical main size as the flex item's *temporary* main size.
|
||||
|
@ -982,7 +982,7 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
|
|||
|
||||
// If the sum of the unfrozen flex items’ flex factors is less than one, multiply the initial free space by this sum.
|
||||
if (auto sum_of_flex_factor_of_unfrozen_items = line.sum_of_flex_factor_of_unfrozen_items(); sum_of_flex_factor_of_unfrozen_items < 1 && initial_free_space.has_value()) {
|
||||
auto value = initial_free_space.value() * sum_of_flex_factor_of_unfrozen_items;
|
||||
auto value = CSSPixels(initial_free_space.value() * sum_of_flex_factor_of_unfrozen_items);
|
||||
// If the magnitude of this value is less than the magnitude of the remaining free space, use this as the remaining free space.
|
||||
if (abs(value) < abs(line.remaining_free_space.value()))
|
||||
line.remaining_free_space = value;
|
||||
|
@ -1004,7 +1004,7 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
|
|||
continue;
|
||||
double ratio = item.flex_factor.value() / sum_of_flex_factor_of_unfrozen_items;
|
||||
// Set the item’s target main size to its flex base size plus a fraction of the remaining free space proportional to the ratio.
|
||||
item.target_main_size = item.flex_base_size + (remaining_free_space_or_zero_if_infinite * ratio);
|
||||
item.target_main_size = item.flex_base_size + remaining_free_space_or_zero_if_infinite.scaled(ratio);
|
||||
}
|
||||
}
|
||||
// If using the flex shrink factor
|
||||
|
@ -1026,7 +1026,7 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
|
|||
|
||||
// Set the item’s target main size to its flex base size minus a fraction of the absolute value of the remaining free space proportional to the ratio.
|
||||
// (Note this may result in a negative inner main size; it will be corrected in the next step.)
|
||||
item.target_main_size = item.flex_base_size - (abs(remaining_free_space_or_zero_if_infinite) * ratio);
|
||||
item.target_main_size = item.flex_base_size - abs(remaining_free_space_or_zero_if_infinite).scaled(ratio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1044,7 +1044,7 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
|
|||
|
||||
auto used_max_main_size = has_main_max_size(item.box)
|
||||
? specified_main_max_size(item.box)
|
||||
: NumericLimits<float>::max();
|
||||
: CSSPixels::max();
|
||||
|
||||
auto original_target_main_size = item.target_main_size;
|
||||
item.target_main_size = css_clamp(item.target_main_size, used_min_main_size, used_max_main_size);
|
||||
|
@ -1123,7 +1123,7 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem&
|
|||
auto const& computed_max_size = this->computed_cross_max_size(item.box);
|
||||
|
||||
auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0;
|
||||
auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits<float>::max();
|
||||
auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : CSSPixels::max();
|
||||
|
||||
// If we have a definite cross size, this is easy! No need to perform layout, we can just use it as-is.
|
||||
if (has_definite_cross_size(item.box)) {
|
||||
|
@ -1339,7 +1339,7 @@ void FlexFormattingContext::distribute_any_remaining_free_space()
|
|||
}
|
||||
break;
|
||||
case CSS::JustifyContent::Center:
|
||||
initial_offset = (inner_main_size(flex_container()) - used_main_space) / 2.0;
|
||||
initial_offset = (inner_main_size(flex_container()) - used_main_space) / 2;
|
||||
if (is_direction_reverse()) {
|
||||
initial_offset = inner_main_size(flex_container()) - initial_offset;
|
||||
}
|
||||
|
@ -1357,9 +1357,9 @@ void FlexFormattingContext::distribute_any_remaining_free_space()
|
|||
if (flex_line.remaining_free_space.has_value())
|
||||
space_between_items = flex_line.remaining_free_space.value() / number_of_items;
|
||||
if (is_direction_reverse()) {
|
||||
initial_offset = inner_main_size(flex_container()) - space_between_items / 2.0;
|
||||
initial_offset = inner_main_size(flex_container()) - space_between_items / 2;
|
||||
} else {
|
||||
initial_offset = space_between_items / 2.0;
|
||||
initial_offset = space_between_items / 2;
|
||||
}
|
||||
break;
|
||||
case CSS::JustifyContent::SpaceEvenly:
|
||||
|
@ -1496,7 +1496,7 @@ void FlexFormattingContext::align_all_flex_items_along_the_cross_axis()
|
|||
// FIXME: Take better care of margins
|
||||
for (auto& flex_line : m_flex_lines) {
|
||||
for (auto& item : flex_line.items) {
|
||||
CSSPixels half_line_size = flex_line.cross_size / 2.0;
|
||||
CSSPixels half_line_size = flex_line.cross_size / 2;
|
||||
switch (alignment_for_item(item.box)) {
|
||||
case CSS::AlignItems::Baseline:
|
||||
// FIXME: Implement this
|
||||
|
@ -1512,7 +1512,7 @@ void FlexFormattingContext::align_all_flex_items_along_the_cross_axis()
|
|||
item.cross_offset = half_line_size - item.cross_size.value() - item.margins.cross_after - item.borders.cross_after - item.padding.cross_after;
|
||||
break;
|
||||
case CSS::AlignItems::Center:
|
||||
item.cross_offset = -(item.cross_size.value() / 2.0);
|
||||
item.cross_offset = -(item.cross_size.value() / 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1573,7 +1573,7 @@ void FlexFormattingContext::align_all_flex_lines()
|
|||
if (is_single_line()) {
|
||||
// For single-line flex containers, we only need to center the line along the cross axis.
|
||||
auto& flex_line = m_flex_lines[0];
|
||||
CSSPixels center_of_line = cross_size_of_flex_container / 2.0;
|
||||
CSSPixels center_of_line = cross_size_of_flex_container / 2;
|
||||
for (auto& item : flex_line.items) {
|
||||
item.cross_offset += center_of_line;
|
||||
}
|
||||
|
@ -1732,15 +1732,15 @@ CSSPixels FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container
|
|||
CSSPixels result = contribution - outer_flex_base_size;
|
||||
if (result > 0) {
|
||||
if (item.box->computed_values().flex_grow() >= 1) {
|
||||
result /= item.box->computed_values().flex_grow();
|
||||
result.scale_by(1 / item.box->computed_values().flex_grow());
|
||||
} else {
|
||||
result *= item.box->computed_values().flex_grow();
|
||||
result.scale_by(item.box->computed_values().flex_grow());
|
||||
}
|
||||
} else if (result < 0) {
|
||||
if (item.scaled_flex_shrink_factor == 0)
|
||||
result = CSSPixels::min();
|
||||
else
|
||||
result /= item.scaled_flex_shrink_factor;
|
||||
result.scale_by(1 / item.scaled_flex_shrink_factor);
|
||||
}
|
||||
|
||||
item.desired_flex_fraction = result.to_double();
|
||||
|
@ -1793,13 +1793,13 @@ CSSPixels FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container
|
|||
product = flex_line.chosen_flex_fraction * static_cast<double>(item.box->computed_values().flex_grow());
|
||||
else if (item.desired_flex_fraction < 0)
|
||||
product = flex_line.chosen_flex_fraction * item.scaled_flex_shrink_factor;
|
||||
auto result = item.flex_base_size + product;
|
||||
auto result = item.flex_base_size + CSSPixels(product);
|
||||
|
||||
auto const& computed_min_size = this->computed_main_min_size(item.box);
|
||||
auto const& computed_max_size = this->computed_main_max_size(item.box);
|
||||
|
||||
auto clamp_min = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
|
||||
auto clamp_max = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_main_max_size(item.box) : NumericLimits<float>::max();
|
||||
auto clamp_max = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_main_max_size(item.box) : CSSPixels::max();
|
||||
|
||||
result = css_clamp(result, clamp_min, clamp_max);
|
||||
|
||||
|
@ -1906,7 +1906,7 @@ CSSPixels FlexFormattingContext::calculate_main_min_content_contribution(FlexIte
|
|||
}();
|
||||
|
||||
auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
|
||||
auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits<float>::max();
|
||||
auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : CSSPixels::max();
|
||||
auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
|
||||
|
||||
return item.add_main_margin_box_sizes(clamped_inner_size);
|
||||
|
@ -1927,7 +1927,7 @@ CSSPixels FlexFormattingContext::calculate_main_max_content_contribution(FlexIte
|
|||
}();
|
||||
|
||||
auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
|
||||
auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits<float>::max();
|
||||
auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : CSSPixels::max();
|
||||
auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
|
||||
|
||||
return item.add_main_margin_box_sizes(clamped_inner_size);
|
||||
|
@ -1959,7 +1959,7 @@ CSSPixels FlexFormattingContext::calculate_cross_min_content_contribution(FlexIt
|
|||
auto const& computed_max_size = this->computed_cross_max_size(item.box);
|
||||
|
||||
auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0;
|
||||
auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits<float>::max();
|
||||
auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : CSSPixels::max();
|
||||
|
||||
auto clamped_inner_size = css_clamp(size, clamp_min, clamp_max);
|
||||
|
||||
|
@ -1978,7 +1978,7 @@ CSSPixels FlexFormattingContext::calculate_cross_max_content_contribution(FlexIt
|
|||
auto const& computed_max_size = this->computed_cross_max_size(item.box);
|
||||
|
||||
auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0;
|
||||
auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits<float>::max();
|
||||
auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : CSSPixels::max();
|
||||
|
||||
auto clamped_inner_size = css_clamp(size, clamp_min, clamp_max);
|
||||
|
||||
|
@ -1992,7 +1992,7 @@ CSSPixels FlexFormattingContext::calculate_width_to_use_when_determining_intrins
|
|||
auto const& computed_min_width = box.computed_values().min_width();
|
||||
auto const& computed_max_width = box.computed_values().max_width();
|
||||
auto clamp_min = (!computed_min_width.is_auto() && (!computed_min_width.contains_percentage())) ? specified_cross_min_size(box) : 0;
|
||||
auto clamp_max = (!computed_max_width.is_none() && (!computed_max_width.contains_percentage())) ? specified_cross_max_size(box) : NumericLimits<float>::max();
|
||||
auto clamp_max = (!computed_max_width.is_none() && (!computed_max_width.contains_percentage())) ? specified_cross_max_size(box) : CSSPixels::max();
|
||||
|
||||
CSSPixels width;
|
||||
if (should_treat_width_as_auto(box, m_available_space_for_items->space) || computed_width.is_fit_content())
|
||||
|
@ -2123,8 +2123,8 @@ void FlexFormattingContext::resolve_cross_axis_auto_margins()
|
|||
if (outer_cross_size < line.cross_size) {
|
||||
CSSPixels remainder = line.cross_size - outer_cross_size;
|
||||
if (item.margins.cross_before_is_auto && item.margins.cross_after_is_auto) {
|
||||
item.margins.cross_before = remainder / 2.0;
|
||||
item.margins.cross_after = remainder / 2.0;
|
||||
item.margins.cross_before = remainder / 2;
|
||||
item.margins.cross_after = remainder / 2;
|
||||
} else if (item.margins.cross_before_is_auto) {
|
||||
item.margins.cross_before = remainder;
|
||||
} else {
|
||||
|
@ -2203,13 +2203,13 @@ CSSPixelPoint FlexFormattingContext::calculate_static_position(Box const& box) c
|
|||
cross_offset = half_line_size - inner_cross_size(box) - cross_margin_after - cross_border_after - cross_padding_after;
|
||||
break;
|
||||
case CSS::AlignItems::Center:
|
||||
cross_offset = -((inner_cross_size(box) + cross_border_before + cross_border_after) / 2.0);
|
||||
cross_offset = -((inner_cross_size(box) + cross_border_before + cross_border_after) / 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
cross_offset += inner_cross_size(flex_container()) / 2.0;
|
||||
cross_offset += inner_cross_size(flex_container()) / 2;
|
||||
|
||||
// The main-axis edges of the static-position rectangle are where the margin edges of the child
|
||||
// would be positioned if it were the sole flex item in the flex container,
|
||||
|
@ -2236,7 +2236,7 @@ CSSPixelPoint FlexFormattingContext::calculate_static_position(Box const& box) c
|
|||
case CSS::JustifyContent::SpaceAround:
|
||||
case CSS::JustifyContent::SpaceEvenly:
|
||||
pack_from_end = false;
|
||||
main_offset = (inner_main_size(flex_container()) - inner_main_size(box) - main_border_before - main_border_after) / 2.0;
|
||||
main_offset = (inner_main_size(flex_container()) - inner_main_size(box) - main_border_before - main_border_after) / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -405,7 +405,7 @@ CSSPixels FormattingContext::tentative_width_for_replaced_element(Box const& box
|
|||
// (used height) * (intrinsic ratio)
|
||||
if ((computed_height.is_auto() && computed_width.is_auto() && !box.has_natural_width() && box.has_natural_height() && box.has_preferred_aspect_ratio())
|
||||
|| (computed_width.is_auto() && !computed_height.is_auto() && box.has_preferred_aspect_ratio())) {
|
||||
return compute_height_for_replaced_element(box, available_space) * static_cast<double>(box.preferred_aspect_ratio().value());
|
||||
return compute_height_for_replaced_element(box, available_space).scaled(static_cast<double>(box.preferred_aspect_ratio().value()));
|
||||
}
|
||||
|
||||
// If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width,
|
||||
|
@ -500,7 +500,7 @@ CSSPixels FormattingContext::tentative_height_for_replaced_element(Box const& bo
|
|||
//
|
||||
// (used width) / (intrinsic ratio)
|
||||
if (computed_height.is_auto() && box.has_preferred_aspect_ratio())
|
||||
return m_state.get(box).content_width() / static_cast<double>(box.preferred_aspect_ratio().value());
|
||||
return CSSPixels(m_state.get(box).content_width() / static_cast<double>(box.preferred_aspect_ratio().value()));
|
||||
|
||||
// Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'.
|
||||
if (computed_height.is_auto() && box.has_natural_height())
|
||||
|
@ -1051,8 +1051,8 @@ CSSPixelPoint FormattingContext::calculate_static_position(Box const& box) const
|
|||
// The purpose of this function is to calculate the approximate position that `box`
|
||||
// would have had if it were position:static.
|
||||
|
||||
CSSPixels x = 0.0f;
|
||||
CSSPixels y = 0.0f;
|
||||
CSSPixels x = 0;
|
||||
CSSPixels y = 0;
|
||||
|
||||
VERIFY(box.parent());
|
||||
if (box.parent()->children_are_inline()) {
|
||||
|
@ -1403,7 +1403,7 @@ CSSPixels FormattingContext::calculate_min_content_height(Layout::Box const& box
|
|||
CSSPixels FormattingContext::calculate_max_content_height(Layout::Box const& box, CSSPixels width) const
|
||||
{
|
||||
if (box.has_preferred_aspect_ratio())
|
||||
return width / static_cast<double>(*box.preferred_aspect_ratio());
|
||||
return CSSPixels(width / static_cast<double>(*box.preferred_aspect_ratio()));
|
||||
|
||||
if (box.has_natural_height())
|
||||
return *box.natural_height();
|
||||
|
@ -1711,10 +1711,10 @@ CSSPixels FormattingContext::box_baseline(Box const& box) const
|
|||
return box_state.content_height() + box_state.margin_box_top();
|
||||
case CSS::VerticalAlign::TextTop:
|
||||
// TextTop: Align the top of the box with the top of the parent's content area (see 10.6.1).
|
||||
return box.computed_values().font_size();
|
||||
return CSSPixels(box.computed_values().font_size());
|
||||
case CSS::VerticalAlign::TextBottom:
|
||||
// TextTop: Align the bottom of the box with the bottom of the parent's content area (see 10.6.1).
|
||||
return box_state.content_height() - (box.containing_block()->font().pixel_metrics().descent * 2);
|
||||
return box_state.content_height() - CSSPixels(box.containing_block()->font().pixel_metrics().descent * 2);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1245,7 +1245,7 @@ void GridFormattingContext::expand_flexible_tracks(AvailableSpace const& availab
|
|||
for (auto& track : tracks) {
|
||||
if (track.max_track_sizing_function.is_flexible_length()) {
|
||||
if (track.max_track_sizing_function.flex_factor() > 1) {
|
||||
result = max(result, track.base_size / track.max_track_sizing_function.flex_factor());
|
||||
result = max(result, CSSPixels(track.base_size / track.max_track_sizing_function.flex_factor()));
|
||||
} else {
|
||||
result = max(result, track.base_size);
|
||||
}
|
||||
|
@ -1273,8 +1273,8 @@ void GridFormattingContext::expand_flexible_tracks(AvailableSpace const& availab
|
|||
// For each flexible track, if the product of the used flex fraction and the track’s flex factor is greater than
|
||||
// the track’s base size, set its base size to that product.
|
||||
for (auto& track : tracks_and_gaps) {
|
||||
if (track.max_track_sizing_function.flex_factor() * flex_fraction > track.base_size) {
|
||||
track.base_size = track.max_track_sizing_function.flex_factor() * flex_fraction;
|
||||
if (flex_fraction.scaled(track.max_track_sizing_function.flex_factor()) > track.base_size) {
|
||||
track.base_size = flex_fraction.scaled(track.max_track_sizing_function.flex_factor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,11 +34,11 @@ void ImageBox::prepare_for_replaced_layout()
|
|||
|
||||
CSSPixels alt_text_width = 0;
|
||||
if (!m_cached_alt_text_width.has_value())
|
||||
m_cached_alt_text_width = font.width(alt);
|
||||
m_cached_alt_text_width = CSSPixels(font.width(alt));
|
||||
alt_text_width = m_cached_alt_text_width.value();
|
||||
|
||||
set_natural_width(alt_text_width + 16);
|
||||
set_natural_height(font.pixel_size() + 16);
|
||||
set_natural_height(CSSPixels(font.pixel_size()) + 16);
|
||||
}
|
||||
|
||||
if (!has_natural_width() && !has_natural_height()) {
|
||||
|
|
|
@ -180,7 +180,7 @@ Optional<InlineLevelIterator::Item> InlineLevelIterator::next_without_lookahead(
|
|||
m_text_node_context->is_last_chunk = true;
|
||||
|
||||
auto& chunk = chunk_opt.value();
|
||||
CSSPixels chunk_width = text_node.font().width(chunk.view) + text_node.font().glyph_spacing();
|
||||
CSSPixels chunk_width = CSSPixels(text_node.font().width(chunk.view) + text_node.font().glyph_spacing());
|
||||
|
||||
if (m_text_node_context->do_respect_linebreaks && chunk.has_breaking_newline) {
|
||||
return Item {
|
||||
|
|
|
@ -386,7 +386,7 @@ void LayoutState::UsedValues::set_node(NodeWithStyleAndBoxModelMetrics& node, Us
|
|||
if (size.is_percentage()) {
|
||||
if (containing_block_has_definite_size) {
|
||||
auto containing_block_size = width ? containing_block_used_values->content_width() : containing_block_used_values->content_height();
|
||||
resolved_definite_size = adjust_for_box_sizing(containing_block_size * static_cast<double>(size.percentage().as_fraction()), size, width);
|
||||
resolved_definite_size = adjust_for_box_sizing(containing_block_size.scaled(size.percentage().as_fraction()), size, width);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -25,7 +25,7 @@ void LineBox::add_fragment(Node const& layout_node, int start, int length, CSSPi
|
|||
m_fragments.last().set_width(m_fragments.last().width() + content_width);
|
||||
} else {
|
||||
CSSPixels x_offset = leading_margin + leading_size + m_width;
|
||||
CSSPixels y_offset = 0.0f;
|
||||
CSSPixels y_offset = 0;
|
||||
m_fragments.append(LineBoxFragment { layout_node, start, length, CSSPixelPoint(x_offset, y_offset), CSSPixelSize(content_width, content_height), border_box_top, border_box_bottom });
|
||||
}
|
||||
m_width += leading_margin + leading_size + content_width + trailing_size + trailing_margin;
|
||||
|
|
|
@ -51,7 +51,7 @@ int LineBoxFragment::text_index_at(CSSPixels x) const
|
|||
Utf8View view(text());
|
||||
|
||||
CSSPixels relative_x = x - absolute_x();
|
||||
float glyph_spacing = font.glyph_spacing();
|
||||
CSSPixels glyph_spacing = CSSPixels(font.glyph_spacing());
|
||||
|
||||
if (relative_x < 0)
|
||||
return 0;
|
||||
|
@ -59,9 +59,9 @@ int LineBoxFragment::text_index_at(CSSPixels x) const
|
|||
CSSPixels width_so_far = 0;
|
||||
for (auto it = view.begin(); it != view.end(); ++it) {
|
||||
auto previous_it = it;
|
||||
CSSPixels glyph_width = font.glyph_or_emoji_width(it);
|
||||
CSSPixels glyph_width = CSSPixels(font.glyph_or_emoji_width(it));
|
||||
|
||||
if ((width_so_far + (glyph_width + glyph_spacing) / 2) > relative_x)
|
||||
if ((width_so_far + glyph_width + glyph_spacing / 2) > relative_x)
|
||||
return m_start + view.byte_offset_of(previous_it);
|
||||
|
||||
width_so_far += glyph_width + glyph_spacing;
|
||||
|
@ -105,8 +105,8 @@ CSSPixelRect LineBoxFragment::selection_rect(Gfx::Font const& font) const
|
|||
|
||||
auto selection_start_in_this_fragment = max(0, range->start_offset() - m_start);
|
||||
auto selection_end_in_this_fragment = min(m_length, range->end_offset() - m_start);
|
||||
auto pixel_distance_to_first_selected_character = font.width(text.substring_view(0, selection_start_in_this_fragment));
|
||||
auto pixel_width_of_selection = font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment)) + 1;
|
||||
auto pixel_distance_to_first_selected_character = CSSPixels(font.width(text.substring_view(0, selection_start_in_this_fragment)));
|
||||
auto pixel_width_of_selection = CSSPixels(font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment))) + 1;
|
||||
|
||||
auto rect = absolute_rect();
|
||||
rect.set_x(rect.x() + pixel_distance_to_first_selected_character);
|
||||
|
@ -121,8 +121,8 @@ CSSPixelRect LineBoxFragment::selection_rect(Gfx::Font const& font) const
|
|||
|
||||
auto selection_start_in_this_fragment = max(0, range->start_offset() - m_start);
|
||||
auto selection_end_in_this_fragment = m_length;
|
||||
auto pixel_distance_to_first_selected_character = font.width(text.substring_view(0, selection_start_in_this_fragment));
|
||||
auto pixel_width_of_selection = font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment)) + 1;
|
||||
auto pixel_distance_to_first_selected_character = CSSPixels(font.width(text.substring_view(0, selection_start_in_this_fragment)));
|
||||
auto pixel_width_of_selection = CSSPixels(font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment))) + 1;
|
||||
|
||||
auto rect = absolute_rect();
|
||||
rect.set_x(rect.x() + pixel_distance_to_first_selected_character);
|
||||
|
@ -137,8 +137,8 @@ CSSPixelRect LineBoxFragment::selection_rect(Gfx::Font const& font) const
|
|||
|
||||
auto selection_start_in_this_fragment = 0;
|
||||
auto selection_end_in_this_fragment = min(range->end_offset() - m_start, m_length);
|
||||
auto pixel_distance_to_first_selected_character = font.width(text.substring_view(0, selection_start_in_this_fragment));
|
||||
auto pixel_width_of_selection = font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment)) + 1;
|
||||
auto pixel_distance_to_first_selected_character = CSSPixels(font.width(text.substring_view(0, selection_start_in_this_fragment)));
|
||||
auto pixel_width_of_selection = CSSPixels(font.width(text.substring_view(selection_start_in_this_fragment, selection_end_in_this_fragment - selection_start_in_this_fragment))) + 1;
|
||||
|
||||
auto rect = absolute_rect();
|
||||
rect.set_x(rect.x() + pixel_distance_to_first_selected_character);
|
||||
|
|
|
@ -195,7 +195,7 @@ void LineBuilder::update_last_line()
|
|||
auto& font = m_context.containing_block().font();
|
||||
auto const line_height = m_context.containing_block().line_height();
|
||||
auto const font_metrics = font.pixel_metrics();
|
||||
auto const typographic_height = font_metrics.ascent + font_metrics.descent;
|
||||
auto const typographic_height = CSSPixels(font_metrics.ascent + font_metrics.descent);
|
||||
auto const leading = line_height - typographic_height;
|
||||
auto const half_leading = leading / 2;
|
||||
return CSSPixels(font_metrics.ascent) + half_leading;
|
||||
|
@ -230,7 +230,7 @@ void LineBuilder::update_last_line()
|
|||
if (length_percentage->is_length())
|
||||
fragment_baseline += length_percentage->length().to_px(fragment.layout_node());
|
||||
else if (length_percentage->is_percentage())
|
||||
fragment_baseline += length_percentage->percentage().as_fraction() * line_height.to_double();
|
||||
fragment_baseline += line_height.scaled(length_percentage->percentage().as_fraction());
|
||||
}
|
||||
|
||||
line_box_baseline = max(line_box_baseline, fragment_baseline);
|
||||
|
@ -284,7 +284,7 @@ void LineBuilder::update_last_line()
|
|||
auto vertical_align_amount = length_percentage->length().to_px(fragment.layout_node());
|
||||
new_fragment_y = y_value_for_alignment(CSS::VerticalAlign::Baseline) - vertical_align_amount;
|
||||
} else if (length_percentage->is_percentage()) {
|
||||
auto vertical_align_amount = length_percentage->percentage().as_fraction() * m_context.containing_block().line_height().to_double();
|
||||
auto vertical_align_amount = m_context.containing_block().line_height().scaled(length_percentage->percentage().as_fraction());
|
||||
new_fragment_y = y_value_for_alignment(CSS::VerticalAlign::Baseline) - vertical_align_amount;
|
||||
}
|
||||
}
|
||||
|
@ -302,17 +302,17 @@ void LineBuilder::update_last_line()
|
|||
bottom_of_inline_box = (fragment.offset().y() + fragment_box_state.content_height() + fragment_box_state.margin_box_bottom());
|
||||
} else {
|
||||
auto font_metrics = fragment.layout_node().font().pixel_metrics();
|
||||
auto typographic_height = font_metrics.ascent + font_metrics.descent;
|
||||
auto typographic_height = CSSPixels(font_metrics.ascent + font_metrics.descent);
|
||||
auto leading = fragment.layout_node().line_height() - typographic_height;
|
||||
auto half_leading = leading / 2;
|
||||
top_of_inline_box = (fragment.offset().y() + fragment.baseline() - font_metrics.ascent - half_leading);
|
||||
bottom_of_inline_box = (fragment.offset().y() + fragment.baseline() + font_metrics.descent + half_leading);
|
||||
top_of_inline_box = (fragment.offset().y() + fragment.baseline() - CSSPixels(font_metrics.ascent) - half_leading);
|
||||
bottom_of_inline_box = (fragment.offset().y() + fragment.baseline() + CSSPixels(font_metrics.descent) + half_leading);
|
||||
}
|
||||
if (auto const* length_percentage = fragment.layout_node().computed_values().vertical_align().get_pointer<CSS::LengthPercentage>()) {
|
||||
if (length_percentage->is_length())
|
||||
bottom_of_inline_box += length_percentage->length().to_px(fragment.layout_node());
|
||||
else if (length_percentage->is_percentage())
|
||||
bottom_of_inline_box += length_percentage->percentage().as_fraction() * m_context.containing_block().line_height().to_double();
|
||||
bottom_of_inline_box += m_context.containing_block().line_height().scaled(length_percentage->percentage().as_fraction());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -300,11 +300,11 @@ static CSSPixels snap_a_length_as_a_border_width(double device_pixels_per_css_pi
|
|||
|
||||
// 3. If len is greater than zero, but less than 1 device pixel, round len up to 1 device pixel.
|
||||
if (device_pixels > 0 && device_pixels < 1)
|
||||
return 1 / device_pixels_per_css_pixel;
|
||||
return CSSPixels(1 / device_pixels_per_css_pixel);
|
||||
|
||||
// 4. If len is greater than 1 device pixel, round it down to the nearest integer number of device pixels.
|
||||
if (device_pixels > 1)
|
||||
return floor(device_pixels) / device_pixels_per_css_pixel;
|
||||
return CSSPixels(floor(device_pixels) / device_pixels_per_css_pixel);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
@ -684,11 +684,11 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
|
|||
// https://www.w3.org/TR/css-backgrounds-3/#valdef-line-width-thin
|
||||
switch (value->to_identifier()) {
|
||||
case CSS::ValueID::Thin:
|
||||
return 1.0;
|
||||
return 1;
|
||||
case CSS::ValueID::Medium:
|
||||
return 3.0;
|
||||
return 3;
|
||||
case CSS::ValueID::Thick:
|
||||
return 5.0;
|
||||
return 5;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
@ -742,7 +742,7 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
|
|||
// FIXME: Converting to pixels isn't really correct - values should be in "user units"
|
||||
// https://svgwg.org/svg2-draft/coords.html#TermUserUnits
|
||||
if (stroke_width->is_number())
|
||||
computed_values.set_stroke_width(CSS::Length::make_px(stroke_width->as_number().number()));
|
||||
computed_values.set_stroke_width(CSS::Length::make_px(CSSPixels(stroke_width->as_number().number())));
|
||||
else if (stroke_width->is_length())
|
||||
computed_values.set_stroke_width(stroke_width->as_length().length());
|
||||
else if (stroke_width->is_percentage())
|
||||
|
|
|
@ -86,13 +86,13 @@ static ViewBoxTransform scale_and_align_viewbox_content(SVG::PreserveAspectRatio
|
|||
case SVG::PreserveAspectRatio::Align::xMidYMid:
|
||||
case SVG::PreserveAspectRatio::Align::xMidYMax:
|
||||
// Align the midpoint X value of the element's ‘viewBox’ with the midpoint X value of the SVG viewport.
|
||||
viewbox_transform.offset.translate_by((svg_box_state.content_width() - (view_box.width * viewbox_transform.scale_factor)) / 2, 0);
|
||||
viewbox_transform.offset.translate_by((svg_box_state.content_width() - CSSPixels(view_box.width * viewbox_transform.scale_factor)) / 2, 0);
|
||||
break;
|
||||
case SVG::PreserveAspectRatio::Align::xMaxYMin:
|
||||
case SVG::PreserveAspectRatio::Align::xMaxYMid:
|
||||
case SVG::PreserveAspectRatio::Align::xMaxYMax:
|
||||
// Align the <min-x>+<width> of the element's ‘viewBox’ with the maximum X value of the SVG viewport.
|
||||
viewbox_transform.offset.translate_by((svg_box_state.content_width() - (view_box.width * viewbox_transform.scale_factor)), 0);
|
||||
viewbox_transform.offset.translate_by((svg_box_state.content_width() - CSSPixels(view_box.width * viewbox_transform.scale_factor)), 0);
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -117,13 +117,13 @@ static ViewBoxTransform scale_and_align_viewbox_content(SVG::PreserveAspectRatio
|
|||
case SVG::PreserveAspectRatio::Align::xMidYMid:
|
||||
case SVG::PreserveAspectRatio::Align::xMaxYMid:
|
||||
// Align the midpoint Y value of the element's ‘viewBox’ with the midpoint Y value of the SVG viewport.
|
||||
viewbox_transform.offset.translate_by(0, (svg_box_state.content_height() - (view_box.height * viewbox_transform.scale_factor)) / 2);
|
||||
viewbox_transform.offset.translate_by(0, (svg_box_state.content_height() - CSSPixels(view_box.height * viewbox_transform.scale_factor)) / 2);
|
||||
break;
|
||||
case SVG::PreserveAspectRatio::Align::xMinYMax:
|
||||
case SVG::PreserveAspectRatio::Align::xMidYMax:
|
||||
case SVG::PreserveAspectRatio::Align::xMaxYMax:
|
||||
// Align the <min-y>+<height> of the element's ‘viewBox’ with the maximum Y value of the SVG viewport.
|
||||
viewbox_transform.offset.translate_by(0, (svg_box_state.content_height() - (view_box.height * viewbox_transform.scale_factor)));
|
||||
viewbox_transform.offset.translate_by(0, (svg_box_state.content_height() - CSSPixels(view_box.height * viewbox_transform.scale_factor)));
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -197,7 +197,7 @@ void SVGFormattingContext::run(Box const& box, LayoutMode layout_mode, Available
|
|||
|
||||
// Stroke increases the path's size by stroke_width/2 per side.
|
||||
auto path_bounding_box = path_transform.map(path.bounding_box()).to_type<CSSPixels>();
|
||||
CSSPixels stroke_width = static_cast<double>(geometry_box.dom_node().visible_stroke_width()) * viewbox_scale;
|
||||
CSSPixels stroke_width = CSSPixels(static_cast<double>(geometry_box.dom_node().visible_stroke_width()) * viewbox_scale);
|
||||
path_bounding_box.inflate(stroke_width, stroke_width);
|
||||
geometry_box_state.set_content_offset(path_bounding_box.top_left());
|
||||
geometry_box_state.set_content_width(path_bounding_box.width());
|
||||
|
|
|
@ -265,11 +265,11 @@ void TableFormattingContext::compute_intrinsic_percentage(size_t max_cell_span)
|
|||
auto cell_start_rc_index = cell_index<RowOrColumn>(cell);
|
||||
auto cell_end_rc_index = cell_start_rc_index + cell_span_value;
|
||||
// 1. Start with the percentage contribution of the cell.
|
||||
CSSPixels cell_contribution = cell_percentage_contribution<RowOrColumn>(cell);
|
||||
CSSPixels cell_contribution = CSSPixels(cell_percentage_contribution<RowOrColumn>(cell));
|
||||
// 2. Subtract the intrinsic percentage width of the column based on cells of span up to N-1 of all columns
|
||||
// that the cell spans. If this gives a negative result, change it to 0%.
|
||||
for (auto rc_index = cell_start_rc_index; rc_index < cell_end_rc_index; rc_index++) {
|
||||
cell_contribution -= rows_or_columns[rc_index].intrinsic_percentage;
|
||||
cell_contribution -= CSSPixels(rows_or_columns[rc_index].intrinsic_percentage);
|
||||
cell_contribution = max(cell_contribution, 0);
|
||||
}
|
||||
// Compute the sum of the non-spanning max-content sizes of all rows / columns spanned by the cell that have an intrinsic percentage
|
||||
|
@ -297,7 +297,7 @@ void TableFormattingContext::compute_intrinsic_percentage(size_t max_cell_span)
|
|||
// columns spanned by the cell that have an intrinsic percentage width of the column based on cells of span up to N-1 equal to 0%.
|
||||
CSSPixels ajusted_cell_contribution;
|
||||
if (width_sum_of_columns_with_zero_intrinsic_percentage != 0) {
|
||||
ajusted_cell_contribution = cell_contribution * rows_or_columns[rc_index].max_size / static_cast<double>(width_sum_of_columns_with_zero_intrinsic_percentage);
|
||||
ajusted_cell_contribution = cell_contribution.scaled(rows_or_columns[rc_index].max_size / static_cast<double>(width_sum_of_columns_with_zero_intrinsic_percentage));
|
||||
} else {
|
||||
// However, if this ratio is undefined because the denominator is zero, instead use the 1 divided by the number of columns
|
||||
// spanned by the cell that have an intrinsic percentage width of the column based on cells of span up to N-1 equal to zero.
|
||||
|
@ -380,12 +380,12 @@ void TableFormattingContext::compute_table_measures()
|
|||
auto clamped_diff_to_baseline_min = min(
|
||||
max(cell_min_size<RowOrColumn>(cell) - baseline_min_content_size - baseline_border_spacing, 0),
|
||||
baseline_max_content_size - baseline_min_content_size);
|
||||
cell_min_contribution += normalized_max_min_diff * clamped_diff_to_baseline_min;
|
||||
cell_min_contribution += CSSPixels(normalized_max_min_diff * clamped_diff_to_baseline_min);
|
||||
// the product of:
|
||||
// - the ratio of the max-content size based on cells of span up to N-1 of the column to the baseline max-content size
|
||||
// - the outer min-content size of the cell minus the baseline max-content size and baseline border spacing, or 0 if this is negative
|
||||
if (baseline_max_content_size != 0) {
|
||||
cell_min_contribution += (rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
|
||||
cell_min_contribution += CSSPixels(rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
|
||||
* max(CSSPixels(0), cell_min_size<RowOrColumn>(cell) - baseline_max_content_size - baseline_border_spacing);
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,7 @@ void TableFormattingContext::compute_table_measures()
|
|||
// - the ratio of the max-content size based on cells of span up to N-1 of the column to the baseline max-content size
|
||||
// - the outer max-content size of the cell minus the baseline max-content size and the baseline border spacing, or 0 if this is negative
|
||||
if (baseline_max_content_size != 0) {
|
||||
cell_max_contribution += (rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
|
||||
cell_max_contribution += CSSPixels(rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
|
||||
* max(CSSPixels(0), cell_max_size<RowOrColumn>(cell) - baseline_max_content_size - baseline_border_spacing);
|
||||
}
|
||||
cell_min_contributions_by_rc_index[rc_index].append(cell_min_contribution);
|
||||
|
@ -461,7 +461,7 @@ void TableFormattingContext::compute_table_width()
|
|||
|
||||
// The row/column-grid width minimum (GRIDMIN) width is the sum of the min-content width
|
||||
// of all the columns plus cell spacing or borders.
|
||||
CSSPixels grid_min = 0.0f;
|
||||
CSSPixels grid_min = 0;
|
||||
for (auto& column : m_columns) {
|
||||
grid_min += column.min_size;
|
||||
}
|
||||
|
@ -469,7 +469,7 @@ void TableFormattingContext::compute_table_width()
|
|||
|
||||
// The row/column-grid width maximum (GRIDMAX) width is the sum of the max-content width
|
||||
// of all the columns plus cell spacing or borders.
|
||||
CSSPixels grid_max = 0.0f;
|
||||
CSSPixels grid_max = 0;
|
||||
for (auto& column : m_columns) {
|
||||
grid_max += column.max_size;
|
||||
}
|
||||
|
@ -496,7 +496,7 @@ void TableFormattingContext::compute_table_width()
|
|||
for (auto& cell : m_cells) {
|
||||
auto const& cell_width = cell.box->computed_values().width();
|
||||
if (cell_width.is_percentage()) {
|
||||
adjusted_used_width = ceil(100 / cell_width.percentage().value() * cell.outer_max_width.to_double());
|
||||
adjusted_used_width = CSSPixels(ceil(100 / cell_width.percentage().value() * cell.outer_max_width.to_double()));
|
||||
if (width_of_table_containing_block.is_definite())
|
||||
used_width = min(max(used_width, adjusted_used_width), width_of_table_containing_block.to_px_or_zero());
|
||||
else
|
||||
|
@ -555,7 +555,7 @@ void TableFormattingContext::assign_columns_width_linear_combination(Vector<CSSP
|
|||
auto candidate_weight = (available_width - columns_total_used_width) / static_cast<double>(columns_total_candidate_width - columns_total_used_width);
|
||||
for (size_t i = 0; i < m_columns.size(); ++i) {
|
||||
auto& column = m_columns[i];
|
||||
column.used_width = candidate_weight * candidate_widths[i] + (1 - candidate_weight) * column.used_width;
|
||||
column.used_width = CSSPixels(candidate_weight * candidate_widths[i] + (1 - candidate_weight) * column.used_width);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -576,7 +576,7 @@ bool TableFormattingContext::distribute_excess_width_proportionally_to_base_widt
|
|||
VERIFY(total_base_width > 0);
|
||||
for (auto& column : m_columns) {
|
||||
if (column_filter(column)) {
|
||||
column.used_width += excess_width * base_width_getter(column) / static_cast<double>(total_base_width);
|
||||
column.used_width += CSSPixels(excess_width * base_width_getter(column) / static_cast<double>(total_base_width));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -618,7 +618,7 @@ bool TableFormattingContext::distribute_excess_width_by_intrinsic_percentage(CSS
|
|||
}
|
||||
for (auto& column : m_columns) {
|
||||
if (column_filter(column)) {
|
||||
column.used_width += excess_width * column.intrinsic_percentage / total_percentage_width;
|
||||
column.used_width += CSSPixels(excess_width * column.intrinsic_percentage / total_percentage_width);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -660,7 +660,7 @@ void TableFormattingContext::distribute_width_to_columns()
|
|||
for (size_t i = 0; i < m_columns.size(); ++i) {
|
||||
auto& column = m_columns[i];
|
||||
if (column.has_intrinsic_percentage) {
|
||||
candidate_widths[i] = max(column.min_size, column.intrinsic_percentage / 100 * available_width);
|
||||
candidate_widths[i] = max(column.min_size, CSSPixels(column.intrinsic_percentage / 100 * available_width));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -990,7 +990,7 @@ void TableFormattingContext::distribute_height_to_rows()
|
|||
for (auto& row : m_rows) {
|
||||
auto weight = row.reference_height / static_cast<double>(sum_reference_height);
|
||||
auto final_height = m_table_height * weight;
|
||||
row.final_height = final_height;
|
||||
row.final_height = CSSPixels(final_height);
|
||||
}
|
||||
} else if (rows_with_auto_height.size() > 0) {
|
||||
// Else, if the table owns any “auto-height” row (a row whose size is only determined by its content size and
|
||||
|
@ -1029,7 +1029,7 @@ void TableFormattingContext::position_row_boxes()
|
|||
for (size_t y = 0; y < m_rows.size(); y++) {
|
||||
auto& row = m_rows[y];
|
||||
auto& row_state = m_state.get_mutable(row.box);
|
||||
CSSPixels row_width = 0.0f;
|
||||
CSSPixels row_width = 0;
|
||||
for (auto& column : m_columns) {
|
||||
row_width += column.used_width;
|
||||
}
|
||||
|
@ -1044,8 +1044,8 @@ void TableFormattingContext::position_row_boxes()
|
|||
CSSPixels row_group_top_offset = table_state.border_top + table_state.padding_top;
|
||||
CSSPixels row_group_left_offset = table_state.border_left + table_state.padding_left;
|
||||
TableGrid::for_each_child_box_matching(table_box(), TableGrid::is_table_row_group, [&](auto& row_group_box) {
|
||||
CSSPixels row_group_height = 0.0f;
|
||||
CSSPixels row_group_width = 0.0f;
|
||||
CSSPixels row_group_height = 0;
|
||||
CSSPixels row_group_width = 0;
|
||||
|
||||
auto& row_group_box_state = m_state.get_mutable(row_group_box);
|
||||
row_group_box_state.set_content_x(row_group_left_offset);
|
||||
|
|
|
@ -38,10 +38,10 @@ HTML::HTMLVideoElement const& VideoBox::dom_node() const
|
|||
void VideoBox::prepare_for_replaced_layout()
|
||||
{
|
||||
auto width = static_cast<float>(dom_node().video_width());
|
||||
set_natural_width(width);
|
||||
set_natural_width(CSSPixels(width));
|
||||
|
||||
auto height = static_cast<float>(dom_node().video_height());
|
||||
set_natural_height(height);
|
||||
set_natural_height(CSSPixels(height));
|
||||
|
||||
if (width != 0 && height != 0)
|
||||
set_natural_aspect_ratio(width / height);
|
||||
|
|
|
@ -161,14 +161,14 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
|||
double max_width_ratio = (background_positioning_area.width() / natural_image_width).to_double();
|
||||
double max_height_ratio = (background_positioning_area.height() / natural_image_height).to_double();
|
||||
double ratio = min(max_width_ratio, max_height_ratio);
|
||||
image_rect.set_size(natural_image_width * ratio, natural_image_height * ratio);
|
||||
image_rect.set_size(natural_image_width.scaled(ratio), natural_image_height.scaled(ratio));
|
||||
break;
|
||||
}
|
||||
case CSS::BackgroundSize::Cover: {
|
||||
double max_width_ratio = (background_positioning_area.width() / natural_image_width).to_double();
|
||||
double max_height_ratio = (background_positioning_area.height() / natural_image_height).to_double();
|
||||
double ratio = max(max_width_ratio, max_height_ratio);
|
||||
image_rect.set_size(natural_image_width * ratio, natural_image_height * ratio);
|
||||
image_rect.set_size(natural_image_width.scaled(ratio), natural_image_height.scaled(ratio));
|
||||
break;
|
||||
}
|
||||
case CSS::BackgroundSize::LengthPercentage: {
|
||||
|
@ -263,7 +263,7 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
|||
repeat_x = false;
|
||||
} else {
|
||||
auto space = fmod(background_positioning_area.width().to_double(), image_rect.width().to_double());
|
||||
x_step = image_rect.width() + (space / static_cast<double>(whole_images - 1));
|
||||
x_step = image_rect.width() + CSSPixels(space / static_cast<double>(whole_images - 1));
|
||||
repeat_x = true;
|
||||
}
|
||||
break;
|
||||
|
@ -294,7 +294,7 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
|||
repeat_y = false;
|
||||
} else {
|
||||
auto space = fmod(background_positioning_area.height().to_float(), image_rect.height().to_float());
|
||||
y_step = image_rect.height() + (static_cast<double>(space) / static_cast<double>(whole_images - 1));
|
||||
y_step = image_rect.height() + CSSPixels(static_cast<double>(space) / static_cast<double>(whole_images - 1));
|
||||
repeat_y = true;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -117,7 +117,7 @@ LinearGradientData resolve_linear_gradient_data(Layout::NodeWithStyleAndBoxModel
|
|||
|
||||
auto resolved_color_stops = resolve_color_stop_positions(
|
||||
node, linear_gradient.color_stop_list(), [&](auto const& length_percentage) {
|
||||
return length_percentage.to_px(node, gradient_length_px).to_float() / static_cast<float>(gradient_length_px);
|
||||
return length_percentage.to_px(node, CSSPixels(gradient_length_px)).to_float() / static_cast<float>(gradient_length_px);
|
||||
},
|
||||
linear_gradient.is_repeating());
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ void MarkerPaintable::paint(PaintContext& context, PaintPhase phase) const
|
|||
CSSPixelRect enclosing = absolute_rect().to_rounded<CSSPixels>();
|
||||
auto device_enclosing = context.enclosing_device_rect(enclosing);
|
||||
|
||||
CSSPixels marker_width = enclosing.height() / 2.0;
|
||||
CSSPixels marker_width = enclosing.height() / 2;
|
||||
|
||||
if (auto const* list_style_image = layout_box().list_style_image()) {
|
||||
CSSPixelRect image_rect {
|
||||
|
|
|
@ -96,7 +96,7 @@ DevicePixelSize PaintContext::rounded_device_size(CSSPixelSize size) const
|
|||
|
||||
CSSPixels PaintContext::scale_to_css_pixels(DevicePixels device_pixels) const
|
||||
{
|
||||
return device_pixels.value() / m_device_pixels_per_css_pixel;
|
||||
return CSSPixels(device_pixels.value() / m_device_pixels_per_css_pixel);
|
||||
}
|
||||
|
||||
CSSPixelPoint PaintContext::scale_to_css_point(DevicePixelPoint point) const
|
||||
|
|
|
@ -258,8 +258,8 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const
|
|||
auto size_text_rect = border_rect;
|
||||
size_text_rect.set_y(border_rect.y() + border_rect.height());
|
||||
size_text_rect.set_top(size_text_rect.top());
|
||||
size_text_rect.set_width((float)font.width(size_text) + 4);
|
||||
size_text_rect.set_height(font.pixel_size() + 4);
|
||||
size_text_rect.set_width(CSSPixels(font.width(size_text)) + 4);
|
||||
size_text_rect.set_height(CSSPixels(font.pixel_size()) + 4);
|
||||
auto size_text_device_rect = context.enclosing_device_rect(size_text_rect).to_type<int>();
|
||||
context.painter().fill_rect(size_text_device_rect, context.palette().color(Gfx::ColorRole::Tooltip));
|
||||
context.painter().draw_rect(size_text_device_rect, context.palette().threed_shadow1());
|
||||
|
@ -503,7 +503,7 @@ static void paint_cursor_if_needed(PaintContext& context, Layout::TextNode const
|
|||
auto fragment_rect = fragment.absolute_rect();
|
||||
|
||||
CSSPixelRect cursor_rect {
|
||||
fragment_rect.x() + text_node.font().width(fragment.text().substring_view(0, text_node.browsing_context().cursor_position().offset() - fragment.start())),
|
||||
fragment_rect.x() + CSSPixels(text_node.font().width(fragment.text().substring_view(0, text_node.browsing_context().cursor_position().offset() - fragment.start()))),
|
||||
fragment_rect.top(),
|
||||
1,
|
||||
fragment_rect.height()
|
||||
|
@ -518,7 +518,7 @@ static void paint_text_decoration(PaintContext& context, Gfx::Painter& painter,
|
|||
{
|
||||
auto& font = fragment.layout_node().font();
|
||||
auto fragment_box = fragment.absolute_rect();
|
||||
CSSPixels glyph_height = font.pixel_size();
|
||||
CSSPixels glyph_height = CSSPixels(font.pixel_size());
|
||||
auto baseline = fragment_box.height() / 2 - (glyph_height + 4) / 2 + glyph_height;
|
||||
|
||||
auto line_color = text_node.computed_values().text_decoration_color();
|
||||
|
@ -526,9 +526,9 @@ static void paint_text_decoration(PaintContext& context, Gfx::Painter& painter,
|
|||
CSSPixels css_line_thickness = [&] {
|
||||
CSS::Length computed_thickness = text_node.computed_values().text_decoration_thickness().resolved(text_node, CSS::Length(1, CSS::Length::Type::Em));
|
||||
if (computed_thickness.is_auto())
|
||||
return max(glyph_height * 0.1, 1.);
|
||||
return max(glyph_height.scaled(0.1), 1);
|
||||
|
||||
return computed_thickness.to_px(text_node).to_double();
|
||||
return computed_thickness.to_px(text_node);
|
||||
}();
|
||||
auto device_line_thickness = context.rounded_device_pixels(css_line_thickness);
|
||||
|
||||
|
@ -550,8 +550,8 @@ static void paint_text_decoration(PaintContext& context, Gfx::Painter& painter,
|
|||
break;
|
||||
case CSS::TextDecorationLine::LineThrough: {
|
||||
auto x_height = font.x_height();
|
||||
line_start_point = context.rounded_device_point(fragment_box.top_left().translated(0, baseline - x_height * 0.5f));
|
||||
line_end_point = context.rounded_device_point(fragment_box.top_right().translated(-1, baseline - x_height * 0.5f));
|
||||
line_start_point = context.rounded_device_point(fragment_box.top_left().translated(0, baseline - x_height * CSSPixels(0.5f)));
|
||||
line_end_point = context.rounded_device_point(fragment_box.top_right().translated(-1, baseline - x_height * CSSPixels(0.5f)));
|
||||
break;
|
||||
}
|
||||
case CSS::TextDecorationLine::Blink:
|
||||
|
|
|
@ -448,12 +448,12 @@ void StackingContext::paint(PaintContext& context) const
|
|||
// to the size of the source (which could add some artefacts, though just scaling the bitmap already does that).
|
||||
// We need to copy the background at the destination because a bunch of our rendering effects now rely on
|
||||
// being able to sample the painter (see border radii, shadows, filters, etc).
|
||||
CSSPixelPoint destination_clipped_fixup {};
|
||||
Gfx::FloatPoint destination_clipped_fixup {};
|
||||
auto try_get_scaled_destination_bitmap = [&]() -> ErrorOr<NonnullRefPtr<Gfx::Bitmap>> {
|
||||
Gfx::IntRect actual_destination_rect;
|
||||
auto bitmap = TRY(context.painter().get_region_bitmap(destination_rect, Gfx::BitmapFormat::BGRA8888, actual_destination_rect));
|
||||
// get_region_bitmap() may clip to a smaller region if the requested rect goes outside the painter, so we need to account for that.
|
||||
destination_clipped_fixup = CSSPixelPoint { destination_rect.location() - actual_destination_rect.location() };
|
||||
destination_clipped_fixup = Gfx::FloatPoint { destination_rect.location() - actual_destination_rect.location() };
|
||||
destination_rect = actual_destination_rect;
|
||||
if (source_rect.size() != transformed_destination_rect.size()) {
|
||||
auto sx = static_cast<float>(source_rect.width()) / transformed_destination_rect.width();
|
||||
|
@ -469,7 +469,7 @@ void StackingContext::paint(PaintContext& context) const
|
|||
return;
|
||||
auto bitmap = bitmap_or_error.release_value_but_fixme_should_propagate_errors();
|
||||
Gfx::Painter painter(bitmap);
|
||||
painter.translate(context.rounded_device_point(-paintable_box().absolute_paint_rect().location() + destination_clipped_fixup).to_type<int>());
|
||||
painter.translate(context.rounded_device_point(-paintable_box().absolute_paint_rect().location() + destination_clipped_fixup.to_type<CSSPixels>()).to_type<int>());
|
||||
auto paint_context = context.clone(painter);
|
||||
paint_internal(paint_context);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Concepts.h>
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/DistinctNumeric.h>
|
||||
#include <AK/Math.h>
|
||||
#include <AK/Traits.h>
|
||||
|
@ -74,16 +75,16 @@ public:
|
|||
m_value = static_cast<int>(value) << fractional_bits;
|
||||
}
|
||||
|
||||
CSSPixels(float value)
|
||||
{
|
||||
if (!isnan(value))
|
||||
m_value = AK::clamp_to_int(value * fixed_point_denominator);
|
||||
}
|
||||
|
||||
CSSPixels(double value)
|
||||
template<FloatingPoint F>
|
||||
explicit CSSPixels(F value)
|
||||
{
|
||||
if (!isnan(value))
|
||||
m_value = AK::clamp_to_int(value * fixed_point_denominator);
|
||||
// Note: The resolution of CSSPixels is 0.015625, so care must be taken when converting
|
||||
// floats/doubles to CSSPixels as small values (such as scale factors) can underflow to zero,
|
||||
// or otherwise produce inaccurate results (when scaled back up).
|
||||
if (m_value == 0 && value != 0)
|
||||
dbgln_if(LIBWEB_CSS_DEBUG, "CSSPixels: Conversion from float or double underflowed to zero");
|
||||
}
|
||||
|
||||
template<Unsigned U>
|
||||
|
@ -217,6 +218,32 @@ public:
|
|||
|
||||
constexpr CSSPixels abs() const { return from_raw(::abs(m_value)); }
|
||||
|
||||
CSSPixels& scale_by(float value)
|
||||
{
|
||||
*this = CSSPixels(to_float() * value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSSPixels& scale_by(double value)
|
||||
{
|
||||
*this = CSSPixels(to_double() * value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSSPixels scaled(float value) const
|
||||
{
|
||||
auto result = *this;
|
||||
result.scale_by(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
CSSPixels scaled(double value) const
|
||||
{
|
||||
auto result = *this;
|
||||
result.scale_by(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
i32 m_value { 0 };
|
||||
};
|
||||
|
|
|
@ -227,7 +227,7 @@ Optional<float> SVGGraphicsElement::stroke_width() const
|
|||
viewport_height = svg_svg_layout_node->computed_values().height().to_px(*svg_svg_layout_node, 0);
|
||||
}
|
||||
}
|
||||
auto scaled_viewport_size = (viewport_width + viewport_height) * 0.5;
|
||||
auto scaled_viewport_size = (viewport_width + viewport_height) * CSSPixels(0.5);
|
||||
return width.to_px(*layout_node(), scaled_viewport_size).to_double();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue