diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index 3037f033e7..6ad1ddf8f7 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -53,10 +53,14 @@ CSSPixels InlineFormattingContext::leftmost_x_offset_at(CSSPixels y) const return left_side_floats_limit_to_right - max(CSSPixels(0), box_in_root_rect.x()); } -CSSPixels InlineFormattingContext::available_space_for_line(CSSPixels y) const +AvailableSize InlineFormattingContext::available_space_for_line(CSSPixels y) const { auto intrusions = parent().intrusion_by_floats_into_box(containing_block(), y); - return m_available_space->width.to_px() - (intrusions.left + intrusions.right); + if (m_available_space->width.is_definite()) { + return AvailableSize::make_definite(m_available_space->width.to_px_or_zero() - (intrusions.left + intrusions.right)); + } else { + return m_available_space->width; + } } CSSPixels InlineFormattingContext::automatic_content_width() const @@ -130,15 +134,19 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l if (should_treat_width_as_auto(box, *m_available_space)) { auto result = calculate_shrink_to_fit_widths(box); - auto available_width = m_available_space->width.to_px() - - box_state.margin_left - - box_state.border_left - - box_state.padding_left - - box_state.padding_right - - box_state.border_right - - box_state.margin_right; + if (m_available_space->width.is_definite()) { + auto available_width = m_available_space->width.to_px_or_zero() + - box_state.margin_left + - box_state.border_left + - box_state.padding_left + - box_state.padding_right + - box_state.border_right + - box_state.margin_right; - unconstrained_width = min(max(result.preferred_minimum_width, available_width), result.preferred_width); + unconstrained_width = min(max(result.preferred_minimum_width, available_width), result.preferred_width); + } else { + unconstrained_width = result.preferred_width; + } } else { if (width_value.contains_percentage() && !m_available_space->width.is_definite()) { // NOTE: We can't resolve percentages yet. We'll have to wait until after inner layout. @@ -195,7 +203,7 @@ void InlineFormattingContext::apply_justification_to_fragments(CSS::TextJustify if (is_last_line || line_box.m_has_forced_break) return; - CSSPixels excess_horizontal_space = line_box.original_available_width() - line_box.width(); + CSSPixels excess_horizontal_space = line_box.original_available_width().to_px_or_zero() - line_box.width(); CSSPixels excess_horizontal_space_including_whitespace = excess_horizontal_space; size_t whitespace_count = 0; for (auto& fragment : line_box.fragments()) { @@ -343,7 +351,7 @@ bool InlineFormattingContext::can_fit_new_line_at_y(CSSPixels y) const }; auto right_edge = [this](auto& space) -> CSSPixels { - return m_available_space->width.to_px() - space.right; + return m_available_space->width.to_px_or_zero() - space.right; }; auto top_left_edge = left_edge(top_intrusions); diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h index 5b32e91d74..1b21b669d7 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h @@ -30,7 +30,7 @@ public: void dimension_box_on_line(Box const&, LayoutMode); CSSPixels leftmost_x_offset_at(CSSPixels y) const; - CSSPixels available_space_for_line(CSSPixels y) const; + AvailableSize available_space_for_line(CSSPixels y) const; bool any_floats_intrude_at_y(CSSPixels y) const; bool can_fit_new_line_at_y(CSSPixels y) const; diff --git a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp index dd2cccb35d..b35d44d72a 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(CSSPixels available_width) +Optional InlineLevelIterator::next(AvailableSize available_width) { if (!m_current_node) return {}; diff --git a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h index fd4b99510e..c8b5e79e0d 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h +++ b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h @@ -51,7 +51,7 @@ public: InlineLevelIterator(Layout::InlineFormattingContext&, LayoutState&, Layout::BlockContainer const&, LayoutMode); - Optional next(CSSPixels available_width); + Optional next(AvailableSize available_width); private: void skip_to_next(); diff --git a/Userland/Libraries/LibWeb/Layout/LineBox.h b/Userland/Libraries/LibWeb/Layout/LineBox.h index b9c691cb22..2ac2e144a0 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBox.h +++ b/Userland/Libraries/LibWeb/Layout/LineBox.h @@ -30,7 +30,7 @@ public: bool is_empty_or_ends_in_whitespace() const; bool is_empty() const { return m_fragments.is_empty() && !m_has_break; } - CSSPixels original_available_width() const { return m_original_available_width; } + AvailableSize original_available_width() const { return m_original_available_width; } CSSPixelRect const& absolute_rect() const { return m_absolute_rect; } void set_absolute_rect(CSSPixelRect const& rect) { m_absolute_rect = rect; } @@ -49,7 +49,7 @@ private: CSSPixels m_baseline { 0 }; // The amount of available width that was originally available when creating this line box. Used for text justification. - CSSPixels m_original_available_width { 0 }; + AvailableSize m_original_available_width { AvailableSize::make_indefinite() }; bool m_has_break { false }; bool m_has_forced_break { false }; diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp index 858d47c67d..69ae43841c 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp @@ -136,7 +136,7 @@ CSSPixels LineBuilder::y_for_float_to_be_inserted_here(Box const& box) bool LineBuilder::should_break(CSSPixels next_item_width) { - if (!isfinite(m_available_width_for_current_line.to_double())) + if (m_available_width_for_current_line.is_max_content()) return false; auto const& line_boxes = m_containing_block_state.line_boxes; @@ -169,7 +169,7 @@ void LineBuilder::update_last_line() 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); - CSSPixels excess_horizontal_space = m_available_width_for_current_line - line_box.width(); + CSSPixels excess_horizontal_space = m_available_width_for_current_line.to_px_or_zero() - line_box.width(); // If (after justification, if any) the inline contents of a line box are too long to fit within it, // then the contents are start-aligned: any content that doesn't fit overflows the line box’s end edge. diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.h b/Userland/Libraries/LibWeb/Layout/LineBuilder.h index 0275d20c95..b054f9d6a3 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.h +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.h @@ -37,7 +37,7 @@ public: return false; } - CSSPixels available_width_for_current_line() const { return m_available_width_for_current_line; } + AvailableSize available_width_for_current_line() const { return m_available_width_for_current_line; } void update_last_line(); @@ -61,7 +61,7 @@ private: InlineFormattingContext& m_context; LayoutState& m_layout_state; LayoutState::UsedValues& m_containing_block_state; - CSSPixels m_available_width_for_current_line { 0 }; + AvailableSize m_available_width_for_current_line { AvailableSize::make_indefinite() }; CSSPixels m_current_y { 0 }; CSSPixels m_max_height_on_current_line { 0 }; CSSPixels m_text_indent { 0 };