Serenity Operating System
at master 101 lines 3.2 kB view raw
1/* 2 * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/Noncopyable.h> 10#include <LibWeb/Layout/BlockContainer.h> 11#include <LibWeb/Layout/InlineNode.h> 12#include <LibWeb/Layout/LayoutState.h> 13#include <LibWeb/Layout/TextNode.h> 14 15namespace Web::Layout { 16 17// This class iterates over all the inline-level objects within an inline formatting context. 18// By repeatedly calling next() with the remaining available width on the current line, 19// it returns an "Item" representing the next piece of inline-level content to be placed on the line. 20class InlineLevelIterator { 21 AK_MAKE_NONCOPYABLE(InlineLevelIterator); 22 AK_MAKE_NONMOVABLE(InlineLevelIterator); 23 24public: 25 struct Item { 26 enum class Type { 27 Text, 28 Element, 29 ForcedBreak, 30 AbsolutelyPositionedElement, 31 FloatingElement, 32 }; 33 Type type {}; 34 Layout::Node const* node { nullptr }; 35 size_t offset_in_node { 0 }; 36 size_t length_in_node { 0 }; 37 CSSPixels width { 0.0f }; 38 CSSPixels padding_start { 0.0f }; 39 CSSPixels padding_end { 0.0f }; 40 CSSPixels border_start { 0.0f }; 41 CSSPixels border_end { 0.0f }; 42 CSSPixels margin_start { 0.0f }; 43 CSSPixels margin_end { 0.0f }; 44 bool is_collapsible_whitespace { false }; 45 46 CSSPixels border_box_width() const 47 { 48 return border_start + padding_start + width + padding_end + border_end; 49 } 50 }; 51 52 InlineLevelIterator(Layout::InlineFormattingContext&, LayoutState&, Layout::BlockContainer const&, LayoutMode); 53 54 Optional<Item> next(CSSPixels available_width); 55 56private: 57 void skip_to_next(); 58 void compute_next(); 59 60 void enter_text_node(Layout::TextNode const&); 61 62 void enter_node_with_box_model_metrics(Layout::NodeWithStyleAndBoxModelMetrics const&); 63 void exit_node_with_box_model_metrics(); 64 65 void add_extra_box_model_metrics_to_item(Item&, bool add_leading_metrics, bool add_trailing_metrics); 66 67 Layout::Node const* next_inline_node_in_pre_order(Layout::Node const& current, Layout::Node const* stay_within); 68 69 Layout::InlineFormattingContext& m_inline_formatting_context; 70 Layout::LayoutState& m_layout_state; 71 Layout::BlockContainer const& m_container; 72 Layout::LayoutState::UsedValues const& m_container_state; 73 Layout::Node const* m_current_node { nullptr }; 74 Layout::Node const* m_next_node { nullptr }; 75 LayoutMode const m_layout_mode; 76 77 struct TextNodeContext { 78 bool do_collapse {}; 79 bool do_wrap_lines {}; 80 bool do_respect_linebreaks {}; 81 bool is_first_chunk {}; 82 bool is_last_chunk {}; 83 TextNode::ChunkIterator chunk_iterator; 84 Optional<TextNode::Chunk> next_chunk {}; 85 }; 86 87 Optional<TextNodeContext> m_text_node_context; 88 89 struct ExtraBoxMetrics { 90 CSSPixels margin { 0 }; 91 CSSPixels border { 0 }; 92 CSSPixels padding { 0 }; 93 }; 94 95 Optional<ExtraBoxMetrics> m_extra_leading_metrics; 96 Optional<ExtraBoxMetrics> m_extra_trailing_metrics; 97 98 Vector<NodeWithStyleAndBoxModelMetrics const&> m_box_model_node_stack; 99}; 100 101}