Frame.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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&, LayoutNode*)> build_layout_tree;
  66. build_layout_tree = [&](const StyledNode& styled_node, LayoutNode* parent_layout_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. for (auto* styled_child = styled_node.first_child(); styled_child; styled_child = styled_child->next_sibling()) {
  72. auto layout_child = build_layout_tree(*styled_child, layout_node.ptr());
  73. if (!layout_child)
  74. continue;
  75. layout_node->append_child(*layout_child);
  76. }
  77. }
  78. return layout_node;
  79. };
  80. return build_layout_tree(styled_root, nullptr);
  81. }
  82. void Frame::layout()
  83. {
  84. if (!m_document)
  85. return;
  86. auto styled_root = generate_style_tree();
  87. auto layout_root = generate_layout_tree(*styled_root);
  88. layout_root->style().size().set_width(m_size.width());
  89. printf("\033[33;1mLayout tree before layout:\033[0m\n");
  90. dump_tree(*layout_root);
  91. layout_root->layout();
  92. printf("\033[33;1mLayout tree after layout:\033[0m\n");
  93. dump_tree(*layout_root);
  94. }