LayoutNode.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #pragma once
  2. #include <AK/NonnullRefPtr.h>
  3. #include <AK/Vector.h>
  4. #include <LibDraw/Rect.h>
  5. #include <LibHTML/CSS/StyleProperties.h>
  6. #include <LibHTML/Layout/BoxModelMetrics.h>
  7. #include <LibHTML/RenderingContext.h>
  8. #include <LibHTML/TreeNode.h>
  9. class Document;
  10. class Element;
  11. class LayoutBlock;
  12. class LayoutNode;
  13. class LayoutNodeWithStyle;
  14. class LineBoxFragment;
  15. class Node;
  16. struct HitTestResult {
  17. RefPtr<LayoutNode> layout_node;
  18. };
  19. class LayoutNode : public TreeNode<LayoutNode> {
  20. public:
  21. virtual ~LayoutNode();
  22. virtual HitTestResult hit_test(const Point&) const;
  23. bool is_anonymous() const { return !m_node; }
  24. const Node* node() const { return m_node; }
  25. const Document& document() const;
  26. template<typename Callback>
  27. inline void for_each_child(Callback callback) const
  28. {
  29. for (auto* node = first_child(); node; node = node->next_sibling())
  30. callback(*node);
  31. }
  32. template<typename Callback>
  33. inline void for_each_child(Callback callback)
  34. {
  35. for (auto* node = first_child(); node; node = node->next_sibling())
  36. callback(*node);
  37. }
  38. virtual const char* class_name() const { return "LayoutNode"; }
  39. virtual bool is_text() const { return false; }
  40. virtual bool is_block() const { return false; }
  41. virtual bool is_replaced() const { return false; }
  42. virtual bool is_box() const { return false; }
  43. virtual bool is_table() const { return false; }
  44. virtual bool is_table_row() const { return false; }
  45. virtual bool is_table_cell() const { return false; }
  46. bool has_style() const { return m_has_style; }
  47. bool is_inline() const { return m_inline; }
  48. void set_inline(bool b) { m_inline = b; }
  49. virtual void layout();
  50. virtual void render(RenderingContext&);
  51. const LayoutBlock* containing_block() const;
  52. virtual LayoutNode& inline_wrapper() { return *this; }
  53. const StyleProperties& style() const;
  54. const LayoutNodeWithStyle* parent() const;
  55. void inserted_into(LayoutNode&) {}
  56. void removed_from(LayoutNode&) {}
  57. virtual void split_into_lines(LayoutBlock& container);
  58. bool is_visible() const { return m_visible; }
  59. void set_visible(bool visible) { m_visible = visible; }
  60. virtual void set_needs_display();
  61. template<typename Callback>
  62. void for_each_fragment_of_this(Callback);
  63. bool children_are_inline() const { return m_children_are_inline; }
  64. void set_children_are_inline(bool value) { m_children_are_inline = value; }
  65. protected:
  66. explicit LayoutNode(const Node*);
  67. private:
  68. friend class LayoutNodeWithStyle;
  69. const Node* m_node { nullptr };
  70. bool m_inline { false };
  71. bool m_has_style { false };
  72. bool m_visible { true };
  73. bool m_children_are_inline { false };
  74. };
  75. class LayoutNodeWithStyle : public LayoutNode {
  76. public:
  77. virtual ~LayoutNodeWithStyle() override {}
  78. const StyleProperties& style() const { return m_style; }
  79. void set_style(const StyleProperties& style) { m_style = style; }
  80. protected:
  81. explicit LayoutNodeWithStyle(const Node* node, NonnullRefPtr<StyleProperties> style)
  82. : LayoutNode(node)
  83. , m_style(move(style))
  84. {
  85. m_has_style = true;
  86. }
  87. private:
  88. NonnullRefPtr<StyleProperties> m_style;
  89. };
  90. class LayoutNodeWithStyleAndBoxModelMetrics : public LayoutNodeWithStyle {
  91. public:
  92. BoxModelMetrics& box_model() { return m_box_model; }
  93. const BoxModelMetrics& box_model() const { return m_box_model; }
  94. protected:
  95. LayoutNodeWithStyleAndBoxModelMetrics(const Node* node, NonnullRefPtr<StyleProperties> style)
  96. : LayoutNodeWithStyle(node, move(style))
  97. {
  98. }
  99. private:
  100. BoxModelMetrics m_box_model;
  101. };
  102. inline const StyleProperties& LayoutNode::style() const
  103. {
  104. if (m_has_style)
  105. return static_cast<const LayoutNodeWithStyle*>(this)->style();
  106. return parent()->style();
  107. }
  108. inline const LayoutNodeWithStyle* LayoutNode::parent() const
  109. {
  110. return static_cast<const LayoutNodeWithStyle*>(TreeNode<LayoutNode>::parent());
  111. }
  112. template<typename T>
  113. inline bool is(const LayoutNode&)
  114. {
  115. return false;
  116. }
  117. template<typename T>
  118. inline bool is(const LayoutNode* node)
  119. {
  120. return !node || is<T>(*node);
  121. }
  122. template<>
  123. inline bool is<LayoutNode>(const LayoutNode&)
  124. {
  125. return true;
  126. }
  127. template<>
  128. inline bool is<LayoutNodeWithStyle>(const LayoutNode& node)
  129. {
  130. return node.has_style();
  131. }
  132. template<typename T>
  133. inline const T& to(const LayoutNode& node)
  134. {
  135. ASSERT(is<T>(node));
  136. return static_cast<const T&>(node);
  137. }
  138. template<typename T>
  139. inline T* to(LayoutNode* node)
  140. {
  141. ASSERT(is<T>(node));
  142. return static_cast<T*>(node);
  143. }
  144. template<typename T>
  145. inline const T* to(const LayoutNode* node)
  146. {
  147. ASSERT(is<T>(node));
  148. return static_cast<const T*>(node);
  149. }
  150. template<typename T>
  151. inline T& to(LayoutNode& node)
  152. {
  153. ASSERT(is<T>(node));
  154. return static_cast<T&>(node);
  155. }