| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  |  * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <LibWeb/CSS/Length.h>
 | 
					
						
							|  |  |  | #include <LibWeb/DOM/Node.h>
 | 
					
						
							|  |  |  | #include <LibWeb/Dump.h>
 | 
					
						
							| 
									
										
										
										
											2021-10-06 20:02:41 +02:00
										 |  |  | #include <LibWeb/Layout/BlockContainer.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-25 20:08:52 +01:00
										 |  |  | #include <LibWeb/Layout/BlockFormattingContext.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | #include <LibWeb/Layout/Box.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | #include <LibWeb/Layout/InlineFormattingContext.h>
 | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  | #include <LibWeb/Layout/InlineLevelIterator.h>
 | 
					
						
							| 
									
										
										
										
											2022-01-19 11:59:44 +01:00
										 |  |  | #include <LibWeb/Layout/LineBuilder.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | #include <LibWeb/Layout/ReplacedBox.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace Web::Layout { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-12 17:01:06 +00:00
										 |  |  | constexpr float text_justification_threshold = 0.1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  | InlineFormattingContext::InlineFormattingContext(FormattingState& state, BlockContainer const& containing_block, BlockFormattingContext& parent) | 
					
						
							| 
									
										
										
										
											2022-02-19 20:13:47 +01:00
										 |  |  |     : FormattingContext(Type::Inline, state, containing_block, &parent) | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 13:21:51 -06:00
										 |  |  | InlineFormattingContext::~InlineFormattingContext() = default; | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-23 15:22:18 +01:00
										 |  |  | BlockFormattingContext& InlineFormattingContext::parent() | 
					
						
							| 
									
										
										
										
											2020-12-05 20:10:39 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-01-23 15:22:18 +01:00
										 |  |  |     return static_cast<BlockFormattingContext&>(*FormattingContext::parent()); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-09-23 16:58:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-23 15:22:18 +01:00
										 |  |  | BlockFormattingContext const& InlineFormattingContext::parent() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return static_cast<BlockFormattingContext const&>(*FormattingContext::parent()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-17 12:30:30 +01:00
										 |  |  | FormattingContext::AvailableSpaceForLineInfo InlineFormattingContext::available_space_for_line(float y) const | 
					
						
							| 
									
										
										
										
											2022-01-23 15:22:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-01-24 02:03:29 +01:00
										 |  |  |     // NOTE: Floats are relative to the BFC root box, not necessarily the containing block of this IFC.
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     auto box_in_root_rect = margin_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root(), m_state); | 
					
						
							| 
									
										
										
										
											2022-01-24 02:03:29 +01:00
										 |  |  |     float y_in_root = box_in_root_rect.y() + y; | 
					
						
							| 
									
										
										
										
											2022-03-17 12:30:30 +01:00
										 |  |  |     auto space = parent().available_space_for_line(y_in_root); | 
					
						
							|  |  |  |     space.right = min(space.right, m_state.get(containing_block()).content_width); | 
					
						
							|  |  |  |     return space; | 
					
						
							| 
									
										
										
										
											2020-12-05 20:10:39 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  | void InlineFormattingContext::run(Box const&, LayoutMode layout_mode) | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |     VERIFY(containing_block().children_are_inline()); | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     generate_line_boxes(layout_mode); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-06 11:31:19 +01:00
										 |  |  |     float min_line_height = containing_block().line_height(); | 
					
						
							| 
									
										
										
										
											2022-01-19 11:59:44 +01:00
										 |  |  |     float max_line_width = 0; | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |     float content_height = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     for (auto& line_box : m_state.get(containing_block()).line_boxes) { | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |         float max_height = min_line_height; | 
					
						
							|  |  |  |         for (auto& fragment : line_box.fragments()) { | 
					
						
							| 
									
										
										
										
											2022-02-26 09:24:40 +01:00
										 |  |  |             max_height = max(max_height, fragment.border_box_height()); | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-01-19 11:59:44 +01:00
										 |  |  |         max_line_width = max(max_line_width, line_box.width()); | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |         content_height += max_height; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 17:42:09 +01:00
										 |  |  |     auto& containing_block_state = m_state.get_mutable(containing_block()); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |     if (layout_mode != LayoutMode::Default) { | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |         containing_block_state.content_width = max_line_width; | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     containing_block_state.content_height = content_height; | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  | void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode layout_mode) | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     auto width_of_containing_block = CSS::Length::make_px(m_state.get(containing_block()).content_width); | 
					
						
							| 
									
										
										
										
											2022-02-21 17:42:09 +01:00
										 |  |  |     auto& box_state = m_state.get_mutable(box); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     auto const& computed_values = box.computed_values(); | 
					
						
							| 
									
										
										
										
											2022-02-14 15:49:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     box_state.margin_left = computed_values.margin().left.resolved(box, width_of_containing_block).to_px(box); | 
					
						
							|  |  |  |     box_state.border_left = computed_values.border_left().width; | 
					
						
							|  |  |  |     box_state.padding_left = computed_values.padding().left.resolved(box, width_of_containing_block).to_px(box); | 
					
						
							|  |  |  |     box_state.margin_right = computed_values.margin().right.resolved(box, width_of_containing_block).to_px(box); | 
					
						
							|  |  |  |     box_state.border_right = computed_values.border_right().width; | 
					
						
							|  |  |  |     box_state.padding_right = computed_values.padding().right.resolved(box, width_of_containing_block).to_px(box); | 
					
						
							| 
									
										
										
										
											2022-02-21 02:16:21 +01:00
										 |  |  |     box_state.padding_top = computed_values.padding().top.resolved(box, width_of_containing_block).to_px(box); | 
					
						
							|  |  |  |     box_state.padding_bottom = computed_values.padding().bottom.resolved(box, width_of_containing_block).to_px(box); | 
					
						
							|  |  |  |     box_state.margin_top = computed_values.margin().top.resolved(box, width_of_containing_block).to_px(box); | 
					
						
							|  |  |  |     box_state.margin_bottom = computed_values.margin().bottom.resolved(box, width_of_containing_block).to_px(box); | 
					
						
							| 
									
										
										
										
											2022-02-14 15:49:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-01 18:55:47 +01:00
										 |  |  |     if (is<ReplacedBox>(box)) { | 
					
						
							| 
									
										
										
										
											2021-06-24 19:53:42 +02:00
										 |  |  |         auto& replaced = verify_cast<ReplacedBox>(box); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |         box_state.content_width = compute_width_for_replaced_element(m_state, replaced); | 
					
						
							|  |  |  |         box_state.content_height = compute_height_for_replaced_element(m_state, replaced); | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (box.is_inline_block()) { | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |         auto const& inline_block = verify_cast<BlockContainer>(box); | 
					
						
							|  |  |  |         auto const& containing_block_state = m_state.get(containing_block()); | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-18 15:10:11 +00:00
										 |  |  |         auto& width_value = inline_block.computed_values().width(); | 
					
						
							| 
									
										
										
										
											2022-02-18 16:50:17 +00:00
										 |  |  |         if (!width_value.has_value() || (width_value->is_length() && width_value->length().is_auto())) { | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |             auto result = calculate_shrink_to_fit_widths(inline_block); | 
					
						
							| 
									
										
										
										
											2020-11-29 22:00:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |             auto available_width = containing_block_state.content_width | 
					
						
							|  |  |  |                 - box_state.margin_left | 
					
						
							|  |  |  |                 - box_state.border_left | 
					
						
							|  |  |  |                 - box_state.padding_left | 
					
						
							|  |  |  |                 - box_state.padding_right | 
					
						
							|  |  |  |                 - box_state.border_right | 
					
						
							|  |  |  |                 - box_state.margin_right; | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             auto width = min(max(result.preferred_minimum_width, available_width), result.preferred_width); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |             box_state.content_width = width; | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |             auto container_width = CSS::Length::make_px(containing_block_state.content_width); | 
					
						
							|  |  |  |             box_state.content_width = width_value->resolved(box, container_width).to_px(inline_block); | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-02-12 19:54:09 +01:00
										 |  |  |         auto independent_formatting_context = layout_inside(inline_block, layout_mode); | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-18 15:10:11 +00:00
										 |  |  |         auto& height_value = inline_block.computed_values().height(); | 
					
						
							| 
									
										
										
										
											2022-02-18 16:50:17 +00:00
										 |  |  |         if (!height_value.has_value() || (height_value->is_length() && height_value->length().is_auto())) { | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |             // FIXME: (10.6.6) If 'height' is 'auto', the height depends on the element's descendants per 10.6.7.
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |             BlockFormattingContext::compute_height(inline_block, m_state); | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |             auto container_height = CSS::Length::make_px(containing_block_state.content_height); | 
					
						
							|  |  |  |             box_state.content_height = height_value->resolved(box, container_height).to_px(inline_block); | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-02-12 19:54:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         independent_formatting_context->parent_context_did_dimension_child_root_box(); | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Non-replaced, non-inline-block, box on a line!?
 | 
					
						
							|  |  |  |     // I don't think we should be here. Dump the box tree so we can take a look at it.
 | 
					
						
							|  |  |  |     dbgln("FIXME: I've been asked to dimension a non-replaced, non-inline-block box on a line:"); | 
					
						
							|  |  |  |     dump_tree(box); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-12 19:32:03 +00:00
										 |  |  | void InlineFormattingContext::apply_justification_to_fragments(FormattingState::NodeState const& containing_block_state, CSS::TextJustify text_justify, LineBox& line_box, bool is_last_line) | 
					
						
							| 
									
										
										
										
											2022-03-12 17:01:06 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-03-12 19:32:03 +00:00
										 |  |  |     switch (text_justify) { | 
					
						
							|  |  |  |     case CSS::TextJustify::None: | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     // FIXME: These two cases currently fall back to auto, handle them as well.
 | 
					
						
							|  |  |  |     case CSS::TextJustify::InterCharacter: | 
					
						
							|  |  |  |     case CSS::TextJustify::InterWord: | 
					
						
							|  |  |  |     case CSS::TextJustify::Auto: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-12 17:01:06 +00:00
										 |  |  |     float excess_horizontal_space = containing_block_state.content_width - line_box.width(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Only justify the text if the excess horizontal space is less than or
 | 
					
						
							|  |  |  |     // equal to 10%, or if we are not looking at the last line box.
 | 
					
						
							|  |  |  |     if (is_last_line && excess_horizontal_space / containing_block_state.content_width > text_justification_threshold) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     float excess_horizontal_space_including_whitespace = excess_horizontal_space; | 
					
						
							|  |  |  |     size_t whitespace_count = 0; | 
					
						
							|  |  |  |     for (auto& fragment : line_box.fragments()) { | 
					
						
							|  |  |  |         if (fragment.is_justifiable_whitespace()) { | 
					
						
							|  |  |  |             ++whitespace_count; | 
					
						
							|  |  |  |             excess_horizontal_space_including_whitespace += fragment.width(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     float justified_space_width = whitespace_count > 0 ? (excess_horizontal_space_including_whitespace / static_cast<float>(whitespace_count)) : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // This is the amount that each fragment will be offset by. If a whitespace
 | 
					
						
							|  |  |  |     // fragment is shorter than the justified space width, it increases to push
 | 
					
						
							|  |  |  |     // subsequent fragments, and decreases to pull them back otherwise.
 | 
					
						
							|  |  |  |     float running_diff = 0; | 
					
						
							|  |  |  |     for (size_t i = 0; i < line_box.fragments().size(); ++i) { | 
					
						
							|  |  |  |         auto& fragment = line_box.fragments()[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         auto offset = fragment.offset(); | 
					
						
							|  |  |  |         offset.translate_by(running_diff, 0); | 
					
						
							|  |  |  |         fragment.set_offset(offset); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (fragment.is_justifiable_whitespace() | 
					
						
							|  |  |  |             && fragment.width() != justified_space_width) { | 
					
						
							|  |  |  |             running_diff += justified_space_width - fragment.width(); | 
					
						
							|  |  |  |             fragment.set_width(justified_space_width); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  | void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-02-21 17:42:09 +01:00
										 |  |  |     auto& containing_block_state = m_state.get_mutable(containing_block()); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     auto& line_boxes = containing_block_state.line_boxes; | 
					
						
							|  |  |  |     line_boxes.clear_with_capacity(); | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     InlineLevelIterator iterator(*this, m_state, containing_block(), layout_mode); | 
					
						
							|  |  |  |     LineBuilder line_builder(*this, m_state); | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (;;) { | 
					
						
							| 
									
										
										
										
											2022-01-19 11:59:44 +01:00
										 |  |  |         auto item_opt = iterator.next(line_builder.available_width_for_current_line()); | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  |         if (!item_opt.has_value()) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         auto& item = item_opt.value(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-21 14:15:10 +01:00
										 |  |  |         // Ignore collapsible whitespace chunks at the start of line, and if the last fragment already ends in whitespace.
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |         if (item.is_collapsible_whitespace && line_boxes.last().is_empty_or_ends_in_whitespace()) | 
					
						
							| 
									
										
										
										
											2022-01-21 14:15:10 +01:00
										 |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 11:59:44 +01:00
										 |  |  |         switch (item.type) { | 
					
						
							|  |  |  |         case InlineLevelIterator::Item::Type::ForcedBreak: | 
					
						
							|  |  |  |             line_builder.break_line(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case InlineLevelIterator::Item::Type::Element: { | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  |             auto& box = verify_cast<Layout::Box>(*item.node); | 
					
						
							| 
									
										
										
										
											2022-02-14 15:52:29 +01:00
										 |  |  |             line_builder.break_if_needed(layout_mode, item.border_box_width(), item.should_force_break); | 
					
						
							| 
									
										
										
										
											2022-03-09 18:46:07 +01:00
										 |  |  |             line_builder.append_box(box, item.border_start + item.padding_start, item.padding_end + item.border_end, item.margin_start, item.margin_end); | 
					
						
							| 
									
										
										
										
											2022-01-19 11:59:44 +01:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-03-07 22:27:09 +01:00
										 |  |  |         case InlineLevelIterator::Item::Type::AbsolutelyPositionedElement: | 
					
						
							|  |  |  |             if (is<Box>(*item.node)) | 
					
						
							|  |  |  |                 parent().add_absolutely_positioned_box(static_cast<Layout::Box const&>(*item.node)); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 11:59:44 +01:00
										 |  |  |         case InlineLevelIterator::Item::Type::Text: { | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  |             auto& text_node = verify_cast<Layout::TextNode>(*item.node); | 
					
						
							| 
									
										
										
										
											2022-02-14 15:52:29 +01:00
										 |  |  |             line_builder.break_if_needed(layout_mode, item.border_box_width(), item.should_force_break); | 
					
						
							| 
									
										
										
										
											2022-01-19 11:59:44 +01:00
										 |  |  |             line_builder.append_text_chunk( | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  |                 text_node, | 
					
						
							|  |  |  |                 item.offset_in_node, | 
					
						
							|  |  |  |                 item.length_in_node, | 
					
						
							| 
									
										
										
										
											2022-02-14 15:52:29 +01:00
										 |  |  |                 item.border_start + item.padding_start, | 
					
						
							|  |  |  |                 item.padding_end + item.border_end, | 
					
						
							| 
									
										
										
										
											2022-03-09 18:46:07 +01:00
										 |  |  |                 item.margin_start, | 
					
						
							|  |  |  |                 item.margin_end, | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  |                 item.width, | 
					
						
							| 
									
										
										
										
											2022-02-26 01:10:43 +01:00
										 |  |  |                 text_node.computed_values().font_size()); | 
					
						
							| 
									
										
										
										
											2022-01-19 11:59:44 +01:00
										 |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     for (auto& line_box : line_boxes) { | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  |         line_box.trim_trailing_whitespace(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-22 10:32:49 +01:00
										 |  |  |     line_builder.remove_last_line_if_empty(); | 
					
						
							| 
									
										
										
										
											2022-03-12 17:01:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto const& containing_block = this->containing_block(); | 
					
						
							|  |  |  |     auto text_align = containing_block.computed_values().text_align(); | 
					
						
							| 
									
										
										
										
											2022-03-12 19:32:03 +00:00
										 |  |  |     auto text_justify = containing_block.computed_values().text_justify(); | 
					
						
							| 
									
										
										
										
											2022-03-12 17:01:06 +00:00
										 |  |  |     if (text_align == CSS::TextAlign::Justify) { | 
					
						
							|  |  |  |         auto const& containing_block_state = m_state.get(containing_block); | 
					
						
							|  |  |  |         for (size_t i = 0; i < line_boxes.size(); i++) { | 
					
						
							|  |  |  |             auto& line_box = line_boxes[i]; | 
					
						
							|  |  |  |             auto is_last_line = i == line_boxes.size() - 1; | 
					
						
							| 
									
										
										
										
											2022-03-12 19:32:03 +00:00
										 |  |  |             apply_justification_to_fragments(containing_block_state, text_justify, line_box, is_last_line); | 
					
						
							| 
									
										
										
										
											2022-03-12 17:01:06 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-17 15:07:19 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | } |