From 76047d19326ee546fce548c40383cfabf4536da0 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Fri, 4 Nov 2022 17:19:11 +0000 Subject: LibWeb: Convert InlineLevelIterator/LineBox/LineBuilder to new px units --- .../LibWeb/Layout/BlockFormattingContext.cpp | 2 +- .../LibWeb/Layout/InlineLevelIterator.cpp | 4 +- .../Libraries/LibWeb/Layout/InlineLevelIterator.h | 24 ++++---- Userland/Libraries/LibWeb/Layout/LayoutState.cpp | 2 +- Userland/Libraries/LibWeb/Layout/LineBox.cpp | 6 +- Userland/Libraries/LibWeb/Layout/LineBox.h | 18 +++--- Userland/Libraries/LibWeb/Layout/LineBuilder.cpp | 68 +++++++++++----------- Userland/Libraries/LibWeb/Layout/LineBuilder.h | 24 ++++---- 8 files changed, 74 insertions(+), 74 deletions(-) (limited to 'Userland/Libraries') diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index 41360c242c..f04289ee49 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -713,7 +713,7 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer // First we place the box normally (to get the right y coordinate.) // If we have a LineBuilder, we're in the middle of inline layout, otherwise this is block layout. if (line_builder) { - auto y = line_builder->y_for_float_to_be_inserted_here(box); + auto y = line_builder->y_for_float_to_be_inserted_here(box).value(); box_state.set_content_y(y + box_state.margin_box_top()); } else { place_block_level_element_in_normal_flow_vertically(box, y + box_state.margin_box_top()); diff --git a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp index 45ae6a53fb..6f9c5155b0 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp @@ -121,7 +121,7 @@ void InlineLevelIterator::skip_to_next() compute_next(); } -Optional InlineLevelIterator::next(float available_width) +Optional InlineLevelIterator::next(CSSPixels available_width) { if (!m_current_node) return {}; @@ -144,7 +144,7 @@ Optional InlineLevelIterator::next(float available_wi m_text_node_context->is_last_chunk = true; auto& chunk = chunk_opt.value(); - float chunk_width = text_node.font().width(chunk.view) + text_node.font().glyph_spacing(); + CSSPixels chunk_width = 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 { diff --git a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h index e96dc9babf..a112f9b214 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h +++ b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h @@ -34,16 +34,16 @@ public: Layout::Node const* node { nullptr }; size_t offset_in_node { 0 }; size_t length_in_node { 0 }; - float width { 0.0f }; - float padding_start { 0.0f }; - float padding_end { 0.0f }; - float border_start { 0.0f }; - float border_end { 0.0f }; - float margin_start { 0.0f }; - float margin_end { 0.0f }; + CSSPixels width { 0.0f }; + CSSPixels padding_start { 0.0f }; + CSSPixels padding_end { 0.0f }; + CSSPixels border_start { 0.0f }; + CSSPixels border_end { 0.0f }; + CSSPixels margin_start { 0.0f }; + CSSPixels margin_end { 0.0f }; bool is_collapsible_whitespace { false }; - float border_box_width() const + CSSPixels border_box_width() const { return border_start + padding_start + width + padding_end + border_end; } @@ -51,7 +51,7 @@ public: InlineLevelIterator(Layout::InlineFormattingContext&, LayoutState&, Layout::BlockContainer const&, LayoutMode); - Optional next(float available_width); + Optional next(CSSPixels available_width); private: void skip_to_next(); @@ -87,9 +87,9 @@ private: Optional m_text_node_context; struct ExtraBoxMetrics { - float margin { 0 }; - float border { 0 }; - float padding { 0 }; + CSSPixels margin { 0 }; + CSSPixels border { 0 }; + CSSPixels padding { 0 }; }; Optional m_extra_leading_metrics; diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp index 60a7b52ed8..7eeac066ab 100644 --- a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp +++ b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp @@ -123,7 +123,7 @@ float box_baseline(LayoutState const& state, Box const& box) } if (!box_state.line_boxes.is_empty()) - return box_state.border_box_top() + box_state.offset.y() + box_state.line_boxes.last().baseline(); + return box_state.border_box_top() + box_state.offset.y() + box_state.line_boxes.last().baseline().value(); if (box.has_children() && !box.children_are_inline()) { auto const* child_box = box.last_child_of_type(); VERIFY(child_box); diff --git a/Userland/Libraries/LibWeb/Layout/LineBox.cpp b/Userland/Libraries/LibWeb/Layout/LineBox.cpp index cbc0d68a20..7c7ea6e530 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/LineBox.cpp @@ -15,7 +15,7 @@ namespace Web::Layout { -void LineBox::add_fragment(Node const& layout_node, int start, int length, float leading_size, float trailing_size, float leading_margin, float trailing_margin, float content_width, float content_height, float border_box_top, float border_box_bottom, LineBoxFragment::Type fragment_type) +void LineBox::add_fragment(Node const& layout_node, int start, int length, CSSPixels leading_size, CSSPixels trailing_size, CSSPixels leading_margin, CSSPixels trailing_margin, CSSPixels content_width, CSSPixels content_height, CSSPixels border_box_top, CSSPixels border_box_bottom, LineBoxFragment::Type fragment_type) { bool text_align_is_justify = layout_node.computed_values().text_align() == CSS::TextAlign::Justify; if (!text_align_is_justify && !m_fragments.is_empty() && &m_fragments.last().layout_node() == &layout_node) { @@ -24,8 +24,8 @@ void LineBox::add_fragment(Node const& layout_node, int start, int length, float m_fragments.last().m_length = (start - m_fragments.last().m_start) + length; m_fragments.last().set_width(m_fragments.last().width() + content_width); } else { - float x_offset = leading_margin + leading_size + m_width; - float y_offset = 0.0f; + CSSPixels x_offset = leading_margin + leading_size + m_width; + CSSPixels y_offset = 0.0f; m_fragments.append(LineBoxFragment { layout_node, start, length, CSSPixelPoint(x_offset, y_offset), CSSPixelSize(content_width, content_height), border_box_top, border_box_bottom, fragment_type }); } m_width += leading_margin + leading_size + content_width + trailing_size + trailing_margin; diff --git a/Userland/Libraries/LibWeb/Layout/LineBox.h b/Userland/Libraries/LibWeb/Layout/LineBox.h index 50986488da..a333943b63 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBox.h +++ b/Userland/Libraries/LibWeb/Layout/LineBox.h @@ -15,12 +15,12 @@ class LineBox { public: LineBox() = default; - float width() const { return m_width; } - float height() const { return m_height; } - float bottom() const { return m_bottom; } - float baseline() const { return m_baseline; } + CSSPixels width() const { return m_width; } + CSSPixels height() const { return m_height; } + CSSPixels bottom() const { return m_bottom; } + CSSPixels baseline() const { return m_baseline; } - void add_fragment(Node const& layout_node, int start, int length, float leading_size, float trailing_size, float leading_margin, float trailing_margin, float content_width, float content_height, float border_box_top, float border_box_bottom, LineBoxFragment::Type = LineBoxFragment::Type::Normal); + void add_fragment(Node const& layout_node, int start, int length, CSSPixels leading_size, CSSPixels trailing_size, CSSPixels leading_margin, CSSPixels trailing_margin, CSSPixels content_width, CSSPixels content_height, CSSPixels border_box_top, CSSPixels border_box_bottom, LineBoxFragment::Type = LineBoxFragment::Type::Normal); Vector const& fragments() const { return m_fragments; } Vector& fragments() { return m_fragments; } @@ -36,10 +36,10 @@ private: friend class LineBuilder; Vector m_fragments; - float m_width { 0 }; - float m_height { 0 }; - float m_bottom { 0 }; - float m_baseline { 0 }; + CSSPixels m_width { 0 }; + CSSPixels m_height { 0 }; + CSSPixels m_bottom { 0 }; + CSSPixels m_baseline { 0 }; }; } diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp index bc430f0c69..8808991502 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp @@ -24,7 +24,7 @@ LineBuilder::~LineBuilder() update_last_line(); } -void LineBuilder::break_line(Optional next_item_width) +void LineBuilder::break_line(Optional next_item_width) { update_last_line(); size_t break_count = 0; @@ -51,7 +51,7 @@ void LineBuilder::begin_new_line(bool increment_y, bool is_first_break_in_sequen // This means we're trying to squeeze past intruding floats. // Scan 1px at a time until we find a Y value where a new line can fit. // FIXME: This is super dumb and inefficient. - float candidate_y = m_current_y + 1; + CSSPixels candidate_y = m_current_y + 1; while (true) { if (m_context.can_fit_new_line_at_y(candidate_y)) break; @@ -73,7 +73,7 @@ LineBox& LineBuilder::ensure_last_line_box() return line_boxes.last(); } -void LineBuilder::append_box(Box const& box, float leading_size, float trailing_size, float leading_margin, float trailing_margin) +void LineBuilder::append_box(Box const& box, CSSPixels leading_size, CSSPixels trailing_size, CSSPixels leading_margin, CSSPixels trailing_margin) { auto& box_state = m_layout_state.get_mutable(box); auto& line_box = ensure_last_line_box(); @@ -86,21 +86,21 @@ void LineBuilder::append_box(Box const& box, float leading_size, float trailing_ }; } -void LineBuilder::append_text_chunk(TextNode const& text_node, size_t offset_in_node, size_t length_in_node, float leading_size, float trailing_size, float leading_margin, float trailing_margin, float content_width, float content_height) +void LineBuilder::append_text_chunk(TextNode const& text_node, size_t offset_in_node, size_t length_in_node, CSSPixels leading_size, CSSPixels trailing_size, CSSPixels leading_margin, CSSPixels trailing_margin, CSSPixels content_width, CSSPixels content_height) { ensure_last_line_box().add_fragment(text_node, offset_in_node, length_in_node, leading_size, trailing_size, leading_margin, trailing_margin, content_width, content_height, 0, 0); m_max_height_on_current_line = max(m_max_height_on_current_line, content_height); } -float LineBuilder::y_for_float_to_be_inserted_here(Box const& box) +CSSPixels LineBuilder::y_for_float_to_be_inserted_here(Box const& box) { auto const& box_state = m_layout_state.get(box); - auto const width = box_state.margin_box_width(); - auto const height = box_state.margin_box_height(); + CSSPixels const width = box_state.margin_box_width(); + CSSPixels const height = box_state.margin_box_height(); - float candidate_y = m_current_y; + CSSPixels candidate_y = m_current_y; - float current_line_width = ensure_last_line_box().width(); + CSSPixels current_line_width = ensure_last_line_box().width(); // If there's already inline content on the current line, check if the new float can fit // alongside the content. If not, place it on the next line. if (current_line_width > 0 && (current_line_width + width) > m_available_width_for_current_line) @@ -110,8 +110,8 @@ float LineBuilder::y_for_float_to_be_inserted_here(Box const& box) // FIXME: This is super dumb, we move 1px downwards per iteration and stop // when we find an Y value where we don't collide with other floats. while (true) { - auto space_at_y_top = m_context.available_space_for_line(candidate_y).value(); - auto space_at_y_bottom = m_context.available_space_for_line(candidate_y + height).value(); + auto space_at_y_top = m_context.available_space_for_line(candidate_y); + auto space_at_y_bottom = m_context.available_space_for_line(candidate_y + height); if (width > space_at_y_top || width > space_at_y_bottom) { if (!m_context.any_floats_intrude_at_y(candidate_y) && !m_context.any_floats_intrude_at_y(candidate_y + height)) { return candidate_y; @@ -123,9 +123,9 @@ float LineBuilder::y_for_float_to_be_inserted_here(Box const& box) } } -bool LineBuilder::should_break(float next_item_width) +bool LineBuilder::should_break(CSSPixels next_item_width) { - if (!isfinite(m_available_width_for_current_line)) + if (!isfinite(m_available_width_for_current_line.value())) return false; auto const& line_boxes = m_containing_block_state.line_boxes; @@ -154,11 +154,11 @@ void LineBuilder::update_last_line() auto text_align = m_context.containing_block().computed_values().text_align(); auto current_line_height = max(m_max_height_on_current_line, m_context.containing_block().line_height()); - float x_offset_top = m_context.leftmost_x_offset_at(m_current_y).value(); - float x_offset_bottom = m_context.leftmost_x_offset_at(m_current_y + current_line_height - 1).value(); - float x_offset = max(x_offset_top, x_offset_bottom); + CSSPixels x_offset_top = m_context.leftmost_x_offset_at(m_current_y); + CSSPixels x_offset_bottom = m_context.leftmost_x_offset_at(m_current_y + current_line_height - 1); + CSSPixels x_offset = max(x_offset_top, x_offset_bottom); - float excess_horizontal_space = m_available_width_for_current_line - line_box.width(); + CSSPixels excess_horizontal_space = m_available_width_for_current_line - line_box.width(); switch (text_align) { case CSS::TextAlign::Center: @@ -185,7 +185,7 @@ void LineBuilder::update_last_line() }(); auto line_box_baseline = [&] { - float line_box_baseline = strut_baseline; + CSSPixels line_box_baseline = strut_baseline; for (auto& fragment : line_box.fragments()) { auto const& font = fragment.layout_node().font(); auto const line_height = fragment.layout_node().line_height(); @@ -196,7 +196,7 @@ void LineBuilder::update_last_line() // The CSS specification calls this AD (A+D, Ascent + Descent). - float fragment_baseline = 0; + CSSPixels fragment_baseline = 0; if (fragment.layout_node().is_text_node()) { fragment_baseline = font_metrics.ascent + half_leading; } else { @@ -221,21 +221,21 @@ void LineBuilder::update_last_line() auto strut_top = m_current_y; auto strut_bottom = m_current_y + m_context.containing_block().line_height(); - float uppermost_box_top = strut_top; - float lowermost_box_bottom = strut_bottom; + CSSPixels uppermost_box_top = strut_top; + CSSPixels lowermost_box_bottom = strut_bottom; for (size_t i = 0; i < line_box.fragments().size(); ++i) { auto& fragment = line_box.fragments()[i]; - float new_fragment_x = roundf(x_offset + fragment.offset().x().value()); - float new_fragment_y = 0; + CSSPixels new_fragment_x = round(x_offset + fragment.offset().x()); + CSSPixels new_fragment_y = 0; auto y_value_for_alignment = [&](CSS::VerticalAlign vertical_align) { switch (vertical_align) { case CSS::VerticalAlign::Baseline: - return m_current_y + line_box_baseline - fragment.baseline().value() + fragment.border_box_top().value(); + return m_current_y + line_box_baseline - fragment.baseline() + fragment.border_box_top(); case CSS::VerticalAlign::Top: - return m_current_y + fragment.border_box_top().value(); + return m_current_y + fragment.border_box_top(); case CSS::VerticalAlign::Middle: case CSS::VerticalAlign::Bottom: case CSS::VerticalAlign::Sub: @@ -243,7 +243,7 @@ void LineBuilder::update_last_line() case CSS::VerticalAlign::TextBottom: case CSS::VerticalAlign::TextTop: // FIXME: These are all 'baseline' - return m_current_y + line_box_baseline - fragment.baseline().value() + fragment.border_box_top().value(); + return m_current_y + line_box_baseline - fragment.baseline() + fragment.border_box_top(); } VERIFY_NOT_REACHED(); }; @@ -258,23 +258,23 @@ void LineBuilder::update_last_line() } } - fragment.set_offset({ new_fragment_x, floorf(new_fragment_y) }); + fragment.set_offset({ new_fragment_x, floor(new_fragment_y) }); - float top_of_inline_box = 0; - float bottom_of_inline_box = 0; + CSSPixels top_of_inline_box = 0; + CSSPixels bottom_of_inline_box = 0; { // FIXME: Support inline-table elements. if (fragment.layout_node().is_replaced_box() || (fragment.layout_node().display().is_inline_outside() && !fragment.layout_node().display().is_flow_inside())) { auto const& fragment_box_state = m_layout_state.get(static_cast(fragment.layout_node())); - top_of_inline_box = (fragment.offset().y() - fragment_box_state.margin_box_top()).value(); - bottom_of_inline_box = (fragment.offset().y() + fragment_box_state.content_height() + fragment_box_state.margin_box_bottom()).value(); + top_of_inline_box = (fragment.offset().y() - fragment_box_state.margin_box_top()); + 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 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).value(); - bottom_of_inline_box = (fragment.offset().y() + fragment.baseline() + font_metrics.descent + half_leading).value(); + 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); } if (auto length_percentage = fragment.layout_node().computed_values().vertical_align().template get_pointer(); length_percentage && length_percentage->is_length()) bottom_of_inline_box += length_percentage->length().to_px(fragment.layout_node()); @@ -306,7 +306,7 @@ void LineBuilder::recalculate_available_space() auto current_line_height = max(m_max_height_on_current_line, m_context.containing_block().line_height()); auto available_at_top_of_line_box = m_context.available_space_for_line(m_current_y); auto available_at_bottom_of_line_box = m_context.available_space_for_line(m_current_y + current_line_height - 1); - m_available_width_for_current_line = min(available_at_bottom_of_line_box, available_at_top_of_line_box).value(); + m_available_width_for_current_line = min(available_at_bottom_of_line_box, available_at_top_of_line_box); } } diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.h b/Userland/Libraries/LibWeb/Layout/LineBuilder.h index 42fa6f65df..5d07a86c3e 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.h +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.h @@ -18,12 +18,12 @@ public: LineBuilder(InlineFormattingContext&, LayoutState&); ~LineBuilder(); - void break_line(Optional next_item_width = {}); - void append_box(Box const&, float leading_size, float trailing_size, float leading_margin, float trailing_margin); - void append_text_chunk(TextNode const&, size_t offset_in_node, size_t length_in_node, float leading_size, float trailing_size, float leading_margin, float trailing_margin, float content_width, float content_height); + void break_line(Optional next_item_width = {}); + void append_box(Box const&, CSSPixels leading_size, CSSPixels trailing_size, CSSPixels leading_margin, CSSPixels trailing_margin); + void append_text_chunk(TextNode const&, size_t offset_in_node, size_t length_in_node, CSSPixels leading_size, CSSPixels trailing_size, CSSPixels leading_margin, CSSPixels trailing_margin, CSSPixels content_width, CSSPixels content_height); // Returns whether a line break occurred. - bool break_if_needed(float next_item_width) + bool break_if_needed(CSSPixels next_item_width) { if (should_break(next_item_width)) { break_line(next_item_width); @@ -32,31 +32,31 @@ public: return false; } - float available_width_for_current_line() const { return m_available_width_for_current_line; } + CSSPixels available_width_for_current_line() const { return m_available_width_for_current_line; } void update_last_line(); void remove_last_line_if_empty(); - float current_y() const { return m_current_y; } - void set_current_y(float y) { m_current_y = y; } + CSSPixels current_y() const { return m_current_y; } + void set_current_y(CSSPixels y) { m_current_y = y; } void recalculate_available_space(); - float y_for_float_to_be_inserted_here(Box const&); + CSSPixels y_for_float_to_be_inserted_here(Box const&); private: void begin_new_line(bool increment_y, bool is_first_break_in_sequence = true); - bool should_break(float next_item_width); + bool should_break(CSSPixels next_item_width); LineBox& ensure_last_line_box(); InlineFormattingContext& m_context; LayoutState& m_layout_state; LayoutState::UsedValues& m_containing_block_state; - float m_available_width_for_current_line { 0 }; - float m_current_y { 0 }; - float m_max_height_on_current_line { 0 }; + CSSPixels m_available_width_for_current_line { 0 }; + CSSPixels m_current_y { 0 }; + CSSPixels m_max_height_on_current_line { 0 }; bool m_last_line_needs_update { false }; }; -- cgit v1.2.3