InlineLevelIterator.h 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Noncopyable.h>
  8. #include <LibWeb/Layout/BlockContainer.h>
  9. #include <LibWeb/Layout/TextNode.h>
  10. namespace Web::Layout {
  11. // This class iterates over all the inline-level objects within an inline formatting context.
  12. // By repeatedly calling next() with the remaining available width on the current line,
  13. // it returns an "Item" representing the next piece of inline-level content to be placed on the line.
  14. class InlineLevelIterator {
  15. AK_MAKE_NONCOPYABLE(InlineLevelIterator);
  16. AK_MAKE_NONMOVABLE(InlineLevelIterator);
  17. public:
  18. struct Item {
  19. enum class Type {
  20. Text,
  21. Element,
  22. ForcedBreak,
  23. };
  24. Type type {};
  25. Layout::Node* node { nullptr };
  26. size_t offset_in_node { 0 };
  27. size_t length_in_node { 0 };
  28. float width { 0.0f };
  29. bool should_force_break { false };
  30. bool is_collapsible_whitespace { false };
  31. };
  32. explicit InlineLevelIterator(Layout::BlockContainer& container, LayoutMode layout_mode)
  33. : m_container(container)
  34. , m_current_node(container.first_child())
  35. , m_layout_mode(layout_mode)
  36. {
  37. }
  38. Optional<Item> next(float available_width);
  39. private:
  40. void skip_to_next();
  41. void enter_text_node(Layout::TextNode&, bool previous_is_empty_or_ends_in_whitespace);
  42. Layout::BlockContainer& m_container;
  43. Layout::Node* m_current_node { nullptr };
  44. LayoutMode const m_layout_mode;
  45. struct TextNodeContext {
  46. bool do_collapse {};
  47. bool do_wrap_lines {};
  48. bool do_respect_linebreaks {};
  49. TextNode::ChunkIterator chunk_iterator;
  50. };
  51. Optional<TextNodeContext> m_text_node_context;
  52. };
  53. }