Frame.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include <AK/Function.h>
  2. #include <LibHTML/CSS/StyleResolver.h>
  3. #include <LibHTML/CSS/StyledNode.h>
  4. #include <LibHTML/DOM/Element.h>
  5. #include <LibHTML/Dump.h>
  6. #include <LibHTML/Frame.h>
  7. #include <LibHTML/Layout/LayoutBlock.h>
  8. #include <LibHTML/Layout/LayoutDocument.h>
  9. #include <LibHTML/Layout/LayoutInline.h>
  10. #include <stdio.h>
  11. Frame::Frame()
  12. : m_size(800, 600)
  13. {
  14. }
  15. Frame::~Frame()
  16. {
  17. }
  18. void Frame::set_document(Document* document)
  19. {
  20. m_document = document;
  21. }
  22. RefPtr<StyledNode> Frame::generate_style_tree()
  23. {
  24. if (!m_document)
  25. return nullptr;
  26. auto& resolver = m_document->style_resolver();
  27. Function<RefPtr<StyledNode>(const Node&, StyledNode*)> resolve_style = [&](const Node& node, StyledNode* parent_styled_node) -> RefPtr<StyledNode> {
  28. RefPtr<StyledNode> styled_node;
  29. if (node.is_element())
  30. styled_node = resolver.create_styled_node(static_cast<const Element&>(node));
  31. else if (node.is_document())
  32. styled_node = resolver.create_styled_node(static_cast<const Document&>(node));
  33. if (!styled_node)
  34. return nullptr;
  35. if (parent_styled_node)
  36. parent_styled_node->append_child(*styled_node);
  37. static_cast<const ParentNode&>(node).for_each_child([&](const Node& child) {
  38. if (!child.is_element())
  39. return;
  40. auto styled_child_node = resolve_style(static_cast<const Element&>(child), styled_node.ptr());
  41. printf("Created StyledNode{%p} for Element{%p}\n", styled_child_node.ptr(), &node);
  42. });
  43. return styled_node;
  44. };
  45. auto styled_root = resolve_style(*m_document, nullptr);
  46. dump_tree(*styled_root);
  47. return styled_root;
  48. }
  49. RefPtr<LayoutNode> Frame::generate_layout_tree(const StyledNode& styled_root)
  50. {
  51. auto create_layout_node = [](const StyledNode& styled_node) -> RefPtr<LayoutNode> {
  52. if (styled_node.node() && styled_node.node()->is_document())
  53. return adopt(*new LayoutDocument(static_cast<const Document&>(*styled_node.node()), styled_node));
  54. switch (styled_node.display()) {
  55. case Display::None:
  56. return nullptr;
  57. case Display::Block:
  58. return adopt(*new LayoutBlock(styled_node.node(), &styled_node));
  59. case Display::Inline:
  60. return adopt(*new LayoutInline(*styled_node.node(), styled_node));
  61. default:
  62. ASSERT_NOT_REACHED();
  63. }
  64. };
  65. Function<RefPtr<LayoutNode>(const StyledNode&)> build_layout_tree;
  66. build_layout_tree = [&](const StyledNode& styled_node) -> RefPtr<LayoutNode> {
  67. auto layout_node = create_layout_node(styled_node);
  68. if (!layout_node)
  69. return nullptr;
  70. if (!styled_node.has_children())
  71. return layout_node;
  72. for (auto* styled_child = styled_node.first_child(); styled_child; styled_child = styled_child->next_sibling()) {
  73. auto layout_child = build_layout_tree(*styled_child);
  74. if (!layout_child)
  75. continue;
  76. if (layout_child->is_inline())
  77. layout_node->inline_wrapper().append_child(*layout_child);
  78. else
  79. layout_node->append_child(*layout_child);
  80. }
  81. return layout_node;
  82. };
  83. return build_layout_tree(styled_root);
  84. }
  85. void Frame::layout()
  86. {
  87. if (!m_document)
  88. return;
  89. auto styled_root = generate_style_tree();
  90. auto layout_root = generate_layout_tree(*styled_root);
  91. layout_root->style().size().set_width(m_size.width());
  92. printf("\033[33;1mLayout tree before layout:\033[0m\n");
  93. dump_tree(*layout_root);
  94. layout_root->layout();
  95. printf("\033[33;1mLayout tree after layout:\033[0m\n");
  96. dump_tree(*layout_root);
  97. }