Diff
Modified: trunk/Source/WebCore/ChangeLog (254805 => 254806)
--- trunk/Source/WebCore/ChangeLog 2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/ChangeLog 2020-01-19 16:30:27 UTC (rev 254806)
@@ -1,3 +1,65 @@
+2020-01-19 Antti Koivisto <[email protected]>
+
+ [LFC][Integration] Use integration specific layout tree builder and data structures
+ https://bugs.webkit.org/show_bug.cgi?id=206483
+
+ Reviewed by Zalan Bujtas.
+
+ The generic tree builder and the LayoutTreeContent class are not optimal for integrated layout.
+
+ This patch adds LayoutIntegration::BoxTree type for building and owning Layout::Boxes for a single flow.
+ It also devirtualizes Layout::Box for faster destruction (the only virtual function was the destructor).
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * layout/integration/LayoutIntegrationBoxTree.cpp: Added.
+ (WebCore::LayoutIntegration::BoxTree::BoxTree):
+ (WebCore::LayoutIntegration::BoxTree::buildTree):
+
+ Only handle supported content.
+
+ (WebCore::LayoutIntegration::BoxTree::layoutBoxForRenderer const):
+ (WebCore::LayoutIntegration::BoxTree::rendererForLayoutBox const):
+
+ For small content just traverse the vector. Construct lookup maps lazily for larger content.
+
+ * layout/integration/LayoutIntegrationBoxTree.h: Copied from Source/WebCore/layout/layouttree/LayoutContainer.h.
+ (WebCore::LayoutIntegration::BoxTree::rootLayoutBox const):
+ (WebCore::LayoutIntegration::BoxTree::rootLayoutBox):
+ * layout/integration/LayoutIntegrationLineLayout.cpp:
+ (WebCore::LayoutIntegration::LineLayout::LineLayout):
+ (WebCore::LayoutIntegration::LineLayout::layout):
+ (WebCore::LayoutIntegration::LineLayout::textBoxesFor const):
+ (WebCore::LayoutIntegration::LineLayout::elementBoxFor const):
+ (WebCore::LayoutIntegration::LineLayout::rootLayoutBox const):
+ (WebCore::LayoutIntegration::LineLayout::rootLayoutBox):
+ (WebCore::LayoutIntegration::LineLayout::hitTest):
+ * layout/integration/LayoutIntegrationLineLayout.h:
+ * layout/layouttree/LayoutBox.cpp:
+ (WebCore::Layout::Box::~Box):
+ * layout/layouttree/LayoutBox.h:
+
+ Devirtualize.
+
+ * layout/layouttree/LayoutContainer.cpp:
+ (WebCore::Layout::Container::appendChild):
+ * layout/layouttree/LayoutContainer.h:
+ * layout/layouttree/LayoutTreeBuilder.cpp:
+ (WebCore::Layout::TreeBuilder::createBox):
+ (WebCore::Layout::TreeBuilder::createTextBox):
+ (WebCore::Layout::TreeBuilder::createContainer):
+ (WebCore::Layout::TreeBuilder::createLayoutBox):
+
+ Factor ownership handling to these create functions.
+
+ (WebCore::Layout::TreeBuilder::buildTableStructure):
+ (WebCore::Layout::TreeBuilder::buildSubTree):
+ * layout/layouttree/LayoutTreeBuilder.h:
+ (WebCore::Layout::LayoutTreeContent::addBox):
+ (WebCore::Layout::LayoutTreeContent::addContainer):
+
+ Put Boxes and Containers to different maps for correct destruction.
+
2020-01-19 Zalan Bujtas <[email protected]>
[LFC][IFC] Move away from placing individual InlineItems on the line
Modified: trunk/Source/WebCore/Sources.txt (254805 => 254806)
--- trunk/Source/WebCore/Sources.txt 2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/Sources.txt 2020-01-19 16:30:27 UTC (rev 254806)
@@ -1455,6 +1455,7 @@
layout/inlineformatting/InlineTextItem.cpp
layout/inlineformatting/LineLayoutContext.cpp
layout/inlineformatting/text/TextUtil.cpp
+layout/integration/LayoutIntegrationBoxTree.cpp
layout/integration/LayoutIntegrationLineLayout.cpp
layout/invalidation/InvalidationContext.cpp
layout/invalidation/InvalidationState.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (254805 => 254806)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-01-19 16:30:27 UTC (rev 254806)
@@ -4814,6 +4814,7 @@
E3FA38641D71812D00AA5950 /* PendingScriptClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FA38611D716E7600AA5950 /* PendingScriptClient.h */; };
E401C27517CE53EC00C41A35 /* ElementIteratorAssertions.h in Headers */ = {isa = PBXBuildFile; fileRef = E401C27417CE53EC00C41A35 /* ElementIteratorAssertions.h */; settings = {ATTRIBUTES = (Private, ); }; };
E401E0A41C3C0B8300F34D10 /* StyleChange.h in Headers */ = {isa = PBXBuildFile; fileRef = E401E0A31C3C0B8300F34D10 /* StyleChange.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E418025523D4549B00FFB071 /* LayoutIntegrationBoxTree.h in Headers */ = {isa = PBXBuildFile; fileRef = E418025323D4549A00FFB071 /* LayoutIntegrationBoxTree.h */; settings = {ATTRIBUTES = (Private, ); }; };
E419041F1CC6486B00C35F5D /* FontSelectorClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E419041E1CC6486B00C35F5D /* FontSelectorClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
E42050172141901B0066EF3B /* ProcessWarming.h in Headers */ = {isa = PBXBuildFile; fileRef = E42050142141901A0066EF3B /* ProcessWarming.h */; settings = {ATTRIBUTES = (Private, ); }; };
E424A39E1330DF0100CF6DC9 /* LegacyTileGridTile.h in Headers */ = {isa = PBXBuildFile; fileRef = E424A39D1330DF0100CF6DC9 /* LegacyTileGridTile.h */; };
@@ -15188,6 +15189,8 @@
E401E0A31C3C0B8300F34D10 /* StyleChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleChange.h; sourceTree = "<group>"; };
E401E0A51C3C0CF700F34D10 /* StyleChange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleChange.cpp; sourceTree = "<group>"; };
E406F3FB1198307D009D59D6 /* ColorData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ColorData.cpp; path = DerivedSources/WebCore/ColorData.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
+ E418025323D4549A00FFB071 /* LayoutIntegrationBoxTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutIntegrationBoxTree.h; sourceTree = "<group>"; };
+ E418025623D454B500FFB071 /* LayoutIntegrationBoxTree.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutIntegrationBoxTree.cpp; sourceTree = "<group>"; };
E419041E1CC6486B00C35F5D /* FontSelectorClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontSelectorClient.h; sourceTree = "<group>"; };
E41EA038119836DB00710BC5 /* CSSPropertyNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSPropertyNames.cpp; path = DerivedSources/WebCore/CSSPropertyNames.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
E41EA0391198374900710BC5 /* CSSValueKeywords.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSValueKeywords.cpp; path = DerivedSources/WebCore/CSSValueKeywords.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -27306,6 +27309,8 @@
E4FB4B1E2395356F003C336A /* integration */ = {
isa = PBXGroup;
children = (
+ E418025623D454B500FFB071 /* LayoutIntegrationBoxTree.cpp */,
+ E418025323D4549A00FFB071 /* LayoutIntegrationBoxTree.h */,
E4ABABDE2360893D00FA4345 /* LayoutIntegrationLineLayout.cpp */,
E4ABABDB236088FD00FA4345 /* LayoutIntegrationLineLayout.h */,
);
@@ -32045,6 +32050,7 @@
458FE40A1589DF0B005609E6 /* RenderSearchField.h in Headers */,
0F11A54F0F39233100C37884 /* RenderSelectionInfo.h in Headers */,
AB247A6D0AFD6383003FA5FD /* RenderSlider.h in Headers */,
+ E418025523D4549B00FFB071 /* LayoutIntegrationBoxTree.h in Headers */,
31955A88160D199200858025 /* RenderSnapshottedPlugIn.h in Headers */,
BC8C8FAE0DDCD31B00B592F4 /* RenderStyle.h in Headers */,
BC5EB6680E81CB7100B25965 /* RenderStyleConstants.h in Headers */,
Added: trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.cpp (0 => 254806)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.cpp (rev 0)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.cpp 2020-01-19 16:30:27 UTC (rev 254806)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "config.h"
+#include "LayoutIntegrationBoxTree.h"
+
+#include "RenderBlockFlow.h"
+#include "RenderChildIterator.h"
+
+namespace WebCore {
+namespace LayoutIntegration {
+
+static constexpr size_t smallTreeThreshold = 8;
+
+static RenderStyle rootBoxStyle(const RenderStyle& style)
+{
+ auto clonedStyle = RenderStyle::clone(style);
+ clonedStyle.setDisplay(DisplayType::Block);
+ return clonedStyle;
+}
+
+BoxTree::BoxTree(const RenderBlockFlow& flow)
+ : m_root({ }, rootBoxStyle(flow.style()))
+{
+ if (flow.isAnonymous())
+ m_root.setIsAnonymous();
+
+ buildTree(flow);
+}
+
+void BoxTree::buildTree(const RenderBlockFlow& flow)
+{
+ for (auto& childRenderer : childrenOfType<RenderObject>(flow)) {
+ std::unique_ptr<Layout::Box> childBox;
+ if (is<RenderText>(childRenderer)) {
+ auto& textRenderer = downcast<RenderText>(childRenderer);
+ auto textContent = Layout::TextContext { textRenderer.text(), textRenderer.canUseSimplifiedTextMeasuring() };
+ childBox = makeUnique<Layout::Box>(WTFMove(textContent), RenderStyle::createAnonymousStyleWithDisplay(m_root.style(), DisplayType::Inline));
+ childBox->setIsAnonymous();
+ } else if (childRenderer.isLineBreak()) {
+ auto clonedStyle = RenderStyle::clone(childRenderer.style());
+ clonedStyle.setDisplay(DisplayType::Inline);
+ clonedStyle.setFloating(Float::No);
+ childBox = makeUnique<Layout::Box>(Layout::Box::ElementAttributes { Layout::Box::ElementType::HardLineBreak }, WTFMove(clonedStyle));
+ }
+ ASSERT(childBox);
+
+ m_root.appendChild(*childBox);
+ m_boxes.append({ WTFMove(childBox), &childRenderer });
+ }
+}
+
+const Layout::Box* BoxTree::layoutBoxForRenderer(const RenderObject& renderer) const
+{
+ if (m_boxes.size() <= smallTreeThreshold) {
+ auto index = m_boxes.findMatching([&](auto& entry) {
+ return entry.renderer == &renderer;
+ });
+ if (index == notFound)
+ return nullptr;
+ return m_boxes[index].box.get();
+ }
+
+ if (m_rendererToBoxMap.isEmpty()) {
+ for (auto& entry : m_boxes)
+ m_rendererToBoxMap.add(entry.renderer, entry.box.get());
+ }
+ return m_rendererToBoxMap.get(&renderer);
+}
+
+const RenderObject* BoxTree::rendererForLayoutBox(const Layout::Box& box) const
+{
+ if (m_boxes.size() <= smallTreeThreshold) {
+ auto index = m_boxes.findMatching([&](auto& entry) {
+ return entry.box.get() == &box;
+ });
+ if (index == notFound)
+ return nullptr;
+ return m_boxes[index].renderer;
+ }
+
+ if (m_boxToRendererMap.isEmpty()) {
+ for (auto& entry : m_boxes)
+ m_boxToRendererMap.add(entry.box.get(), entry.renderer);
+ }
+ return m_boxToRendererMap.get(&box);
+}
+
+}
+}
+
+#endif
+
+
Copied: trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.h (from rev 254805, trunk/Source/WebCore/layout/layouttree/LayoutContainer.h) (0 => 254806)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.h (rev 0)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.h 2020-01-19 16:30:27 UTC (rev 254806)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "LayoutContainer.h"
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class RenderBlockFlow;
+
+namespace LayoutIntegration {
+
+class BoxTree {
+public:
+ BoxTree(const RenderBlockFlow&);
+
+ const Layout::Container& rootLayoutBox() const { return m_root; }
+ Layout::Container& rootLayoutBox() { return m_root; }
+
+ const Layout::Box* layoutBoxForRenderer(const RenderObject&) const;
+ const RenderObject* rendererForLayoutBox(const Layout::Box&) const;
+
+private:
+ void buildTree(const RenderBlockFlow&);
+
+ Layout::Container m_root;
+ struct BoxAndRenderer {
+ std::unique_ptr<const Layout::Box> box;
+ const RenderObject* renderer { nullptr };
+ };
+ Vector<BoxAndRenderer, 1> m_boxes;
+
+ mutable HashMap<const RenderObject*, const Layout::Box*> m_rendererToBoxMap;
+ mutable HashMap<const Layout::Box*, const RenderObject*> m_boxToRendererMap;
+};
+
+}
+}
+
+#endif
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp (254805 => 254806)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp 2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp 2020-01-19 16:30:27 UTC (rev 254806)
@@ -52,8 +52,8 @@
LineLayout::LineLayout(const RenderBlockFlow& flow)
: m_flow(flow)
+ , m_boxTree(flow)
{
- m_treeContent = Layout::TreeBuilder::buildLayoutTreeForIntegration(flow);
}
LineLayout::~LineLayout() = default;
@@ -96,7 +96,7 @@
void LineLayout::layout()
{
if (!m_layoutState) {
- m_layoutState.emplace(m_flow.document(), m_treeContent->rootLayoutBox());
+ m_layoutState.emplace(m_flow.document(), m_boxTree.rootLayoutBox());
m_layoutState->setIsIntegratedRootBoxFirstChild(m_flow.parent()->firstChild() == &m_flow);
}
@@ -176,7 +176,7 @@
auto* inlineContent = displayInlineContent();
if (!inlineContent)
return { };
- auto* layoutBox = m_treeContent->layoutBoxForRenderer(renderText);
+ auto* layoutBox = m_boxTree.layoutBoxForRenderer(renderText);
ASSERT(layoutBox);
Optional<size_t> firstIndex;
@@ -201,7 +201,7 @@
auto* inlineContent = displayInlineContent();
if (!inlineContent)
return { };
- auto* layoutBox = m_treeContent->layoutBoxForRenderer(renderLineBreak);
+ auto* layoutBox = m_boxTree.layoutBoxForRenderer(renderLineBreak);
ASSERT(layoutBox);
for (size_t i = 0; i < inlineContent->runs.size(); ++i) {
@@ -215,12 +215,12 @@
const Layout::Container& LineLayout::rootLayoutBox() const
{
- return m_treeContent->rootLayoutBox();
+ return m_boxTree.rootLayoutBox();
}
Layout::Container& LineLayout::rootLayoutBox()
{
- return m_treeContent->rootLayoutBox();
+ return m_boxTree.rootLayoutBox();
}
void LineLayout::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -314,7 +314,7 @@
if (style.visibility() != Visibility::Visible || style.pointerEvents() == PointerEvents::None)
continue;
- auto& renderer = const_cast<RenderObject&>(*m_treeContent->rendererForLayoutBox(run.layoutBox()));
+ auto& renderer = const_cast<RenderObject&>(*m_boxTree.rendererForLayoutBox(run.layoutBox()));
renderer.updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
if (result.addNodeToListBasedTestResult(renderer.node(), request, locationInContainer, runRect) == HitTestProgress::Stop)
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h (254805 => 254806)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h 2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h 2020-01-19 16:30:27 UTC (rev 254806)
@@ -27,6 +27,7 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+#include "LayoutIntegrationBoxTree.h"
#include "LayoutPoint.h"
#include "LayoutState.h"
#include "LineLayoutTraversal.h"
@@ -86,7 +87,7 @@
ShadowData* debugTextShadow();
const RenderBlockFlow& m_flow;
- std::unique_ptr<Layout::LayoutTreeContent> m_treeContent;
+ BoxTree m_boxTree;
Optional<Layout::LayoutState> m_layoutState;
LayoutUnit m_contentLogicalHeight;
};
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp (254805 => 254806)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2020-01-19 16:30:27 UTC (rev 254806)
@@ -65,7 +65,8 @@
Box::~Box()
{
- removeRareData();
+ if (UNLIKELY(m_hasRareData))
+ removeRareData();
}
void Box::updateStyle(const RenderStyle& newStyle)
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.h (254805 => 254806)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2020-01-19 16:30:27 UTC (rev 254806)
@@ -71,7 +71,7 @@
Box(Optional<ElementAttributes>, RenderStyle&&);
Box(TextContext&&, RenderStyle&&);
- virtual ~Box();
+ ~Box();
bool establishesFormattingContext() const;
bool establishesBlockFormattingContext() const;
Modified: trunk/Source/WebCore/layout/layouttree/LayoutContainer.cpp (254805 => 254806)
--- trunk/Source/WebCore/layout/layouttree/LayoutContainer.cpp 2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutContainer.cpp 2020-01-19 16:30:27 UTC (rev 254806)
@@ -91,6 +91,19 @@
m_lastChild = &childBox;
}
+void Container::appendChild(Box& childBox)
+{
+ childBox.setParent(*this);
+
+ if (m_lastChild) {
+ m_lastChild->setNextSibling(childBox);
+ childBox.setPreviousSibling(*m_lastChild);
+ } else
+ m_firstChild = &childBox;
+
+ m_lastChild = &childBox;
}
+
}
+}
#endif
Modified: trunk/Source/WebCore/layout/layouttree/LayoutContainer.h (254805 => 254806)
--- trunk/Source/WebCore/layout/layouttree/LayoutContainer.h 2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutContainer.h 2020-01-19 16:30:27 UTC (rev 254806)
@@ -57,6 +57,7 @@
void setFirstChild(Box&);
void setLastChild(Box&);
+ void appendChild(Box&);
private:
Box* m_firstChild { nullptr };
Modified: trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp (254805 => 254806)
--- trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp 2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp 2020-01-19 16:30:27 UTC (rev 254806)
@@ -132,33 +132,41 @@
return layoutTreeContent;
}
-std::unique_ptr<Layout::LayoutTreeContent> TreeBuilder::buildLayoutTreeForIntegration(const RenderBlockFlow& renderBlockFlow)
+TreeBuilder::TreeBuilder(LayoutTreeContent& layoutTreeContent)
+ : m_layoutTreeContent(layoutTreeContent)
{
- PhaseScope scope(Phase::Type::TreeBuilding);
+}
- auto clonedStyle = RenderStyle::clone(renderBlockFlow.style());
- clonedStyle.setDisplay(DisplayType::Block);
+void TreeBuilder::buildTree()
+{
+ buildSubTree(m_layoutTreeContent.rootRenderer(), m_layoutTreeContent.rootLayoutBox());
+}
- auto rootLayoutContainer = makeUnique<Container>(Box::ElementAttributes { Box::ElementType::GenericElement }, WTFMove(clonedStyle));
- if (renderBlockFlow.isAnonymous())
- rootLayoutContainer->setIsAnonymous();
-
- auto layoutTreeContent = makeUnique<LayoutTreeContent>(renderBlockFlow, WTFMove(rootLayoutContainer));
- TreeBuilder(*layoutTreeContent).buildTree();
- return layoutTreeContent;
+Box& TreeBuilder::createBox(Optional<Box::ElementAttributes> elementAttributes, RenderStyle&& style)
+{
+ auto newBox = makeUnique<Box>(elementAttributes, WTFMove(style));
+ auto& box = *newBox;
+ m_layoutTreeContent.addBox(WTFMove(newBox));
+ return box;
}
-TreeBuilder::TreeBuilder(LayoutTreeContent& layoutTreeContent)
- : m_layoutTreeContent(layoutTreeContent)
+Box& TreeBuilder::createTextBox(TextContext&& textContent, RenderStyle&& style)
{
+ auto newBox = makeUnique<Box>(WTFMove(textContent), WTFMove(style));
+ auto& box = *newBox;
+ m_layoutTreeContent.addBox(WTFMove(newBox));
+ return box;
}
-void TreeBuilder::buildTree()
+Container& TreeBuilder::createContainer(Optional<Box::ElementAttributes> elementAttributes, RenderStyle&& style)
{
- buildSubTree(m_layoutTreeContent.rootRenderer(), m_layoutTreeContent.rootLayoutBox());
+ auto newContainer = makeUnique<Container>(elementAttributes, WTFMove(style));
+ auto& container = *newContainer;
+ m_layoutTreeContent.addContainer(WTFMove(newContainer));
+ return container;
}
-std::unique_ptr<Box> TreeBuilder::createLayoutBox(const Container& parentContainer, const RenderObject& childRenderer)
+Box* TreeBuilder::createLayoutBox(const Container& parentContainer, const RenderObject& childRenderer)
{
auto elementAttributes = [] (const RenderElement& renderer) -> Optional<Box::ElementAttributes> {
if (renderer.isDocumentElementRenderer())
@@ -178,7 +186,7 @@
return WTF::nullopt;
};
- std::unique_ptr<Box> childLayoutBox;
+ Box* childLayoutBox = nullptr;
if (is<RenderText>(childRenderer)) {
auto& textRenderer = downcast<RenderText>(childRenderer);
// RenderText::text() has already applied text-transform and text-security properties.
@@ -185,9 +193,9 @@
String text = textRenderer.text();
auto textContent = TextContext { text, canUseSimplifiedTextMeasuring(text, parentContainer.style().fontCascade(), parentContainer.style().collapseWhiteSpace()) };
if (parentContainer.style().display() == DisplayType::Inline)
- childLayoutBox = makeUnique<Box>(WTFMove(textContent), RenderStyle::clone(parentContainer.style()));
+ childLayoutBox = &createTextBox(WTFMove(textContent), RenderStyle::clone(parentContainer.style()));
else
- childLayoutBox = makeUnique<Box>(WTFMove(textContent), RenderStyle::createAnonymousStyleWithDisplay(parentContainer.style(), DisplayType::Inline));
+ childLayoutBox = &createTextBox(WTFMove(textContent), RenderStyle::createAnonymousStyleWithDisplay(parentContainer.style(), DisplayType::Inline));
childLayoutBox->setIsAnonymous();
} else {
auto& renderer = downcast<RenderElement>(childRenderer);
@@ -198,16 +206,16 @@
if (is<RenderLineBreak>(renderer)) {
clonedStyle.setDisplay(DisplayType::Inline);
clonedStyle.setFloating(Float::No);
- childLayoutBox = makeUnique<Box>(elementAttributes(renderer), WTFMove(clonedStyle));
+ childLayoutBox = &createBox(elementAttributes(renderer), WTFMove(clonedStyle));
} else if (is<RenderTable>(renderer)) {
// Construct the principal table wrapper box (and not the table box itself).
- childLayoutBox = makeUnique<Container>(Box::ElementAttributes { Box::ElementType::TableWrapperBox }, WTFMove(clonedStyle));
+ childLayoutBox = &createContainer(Box::ElementAttributes { Box::ElementType::TableWrapperBox }, WTFMove(clonedStyle));
childLayoutBox->setIsAnonymous();
} else if (is<RenderReplaced>(renderer)) {
if (displayType == DisplayType::Block)
- childLayoutBox = makeUnique<Box>(elementAttributes(renderer), WTFMove(clonedStyle));
+ childLayoutBox = &createBox(elementAttributes(renderer), WTFMove(clonedStyle));
else
- childLayoutBox = makeUnique<Box>(elementAttributes(renderer), WTFMove(clonedStyle));
+ childLayoutBox = &createBox(elementAttributes(renderer), WTFMove(clonedStyle));
// FIXME: We don't yet support all replaced elements and this is temporary anyway.
if (childLayoutBox->replaced())
childLayoutBox->replaced()->setIntrinsicSize(downcast<RenderReplaced>(renderer).intrinsicSize());
@@ -223,20 +231,20 @@
if (auto offset = accumulatedOffsetForInFlowPositionedContinuation(downcast<RenderBox>(renderer))) {
clonedStyle.setTop({ offset->height(), Fixed });
clonedStyle.setLeft({ offset->width(), Fixed });
- childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+ childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
} else
- childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+ childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
} else if (displayType == DisplayType::Inline)
- childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+ childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
else if (displayType == DisplayType::InlineBlock)
- childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+ childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
else if (displayType == DisplayType::TableCaption || displayType == DisplayType::TableCell) {
- childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+ childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
} else if (displayType == DisplayType::TableRowGroup || displayType == DisplayType::TableHeaderGroup || displayType == DisplayType::TableFooterGroup
|| displayType == DisplayType::TableRow || displayType == DisplayType::TableColumnGroup) {
- childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+ childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
} else if (displayType == DisplayType::TableColumn) {
- childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+ childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
auto& tableColElement = static_cast<HTMLTableColElement&>(*renderer.element());
auto columnWidth = tableColElement.width();
if (!columnWidth.isEmpty())
@@ -245,7 +253,7 @@
childLayoutBox->setColumnSpan(tableColElement.span());
} else {
ASSERT_NOT_IMPLEMENTED_YET();
- return { };
+ return nullptr;
}
}
@@ -273,39 +281,34 @@
auto* tableChild = tableRenderer.firstChild();
while (is<RenderTableCaption>(tableChild)) {
auto& captionRenderer = *tableChild;
- auto captionBox = createLayoutBox(tableWrapperBox, captionRenderer);
+ auto* captionBox = createLayoutBox(tableWrapperBox, captionRenderer);
appendChild(tableWrapperBox, *captionBox);
auto& captionContainer = downcast<Container>(*captionBox);
buildSubTree(downcast<RenderElement>(captionRenderer), captionContainer);
- m_layoutTreeContent.addBox(WTFMove(captionBox));
tableChild = tableChild->nextSibling();
}
- auto tableBox = makeUnique<Container>(Box::ElementAttributes { Box::ElementType::TableBox }, RenderStyle::clone(tableRenderer.style()));
- appendChild(tableWrapperBox, *tableBox);
+ auto& tableBox = createContainer(Box::ElementAttributes { Box::ElementType::TableBox }, RenderStyle::clone(tableRenderer.style()));
+ appendChild(tableWrapperBox, tableBox);
auto* sectionRenderer = tableChild;
while (sectionRenderer) {
- auto sectionBox = createLayoutBox(*tableBox, *sectionRenderer);
- appendChild(*tableBox, *sectionBox);
+ auto* sectionBox = createLayoutBox(tableBox, *sectionRenderer);
+ appendChild(tableBox, *sectionBox);
auto& sectionContainer = downcast<Container>(*sectionBox);
buildSubTree(downcast<RenderElement>(*sectionRenderer), sectionContainer);
- m_layoutTreeContent.addBox(WTFMove(sectionBox));
sectionRenderer = sectionRenderer->nextSibling();
}
- m_layoutTreeContent.addBox(WTFMove(tableBox));
}
void TreeBuilder::buildSubTree(const RenderElement& parentRenderer, Container& parentContainer)
{
for (auto& childRenderer : childrenOfType<RenderObject>(parentRenderer)) {
- auto childLayoutBox = createLayoutBox(parentContainer, childRenderer);
+ auto* childLayoutBox = createLayoutBox(parentContainer, childRenderer);
appendChild(parentContainer, *childLayoutBox);
if (childLayoutBox->isTableWrapperBox())
buildTableStructure(downcast<RenderTable>(childRenderer), downcast<Container>(*childLayoutBox));
else if (is<Container>(*childLayoutBox))
buildSubTree(downcast<RenderElement>(childRenderer), downcast<Container>(*childLayoutBox));
-
- m_layoutTreeContent.addBox(WTFMove(childLayoutBox));
}
}
Modified: trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h (254805 => 254806)
--- trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h 2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h 2020-01-19 16:30:27 UTC (rev 254806)
@@ -27,6 +27,7 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+#include "LayoutContainer.h"
#include <wtf/IsoMalloc.h>
#include <wtf/WeakPtr.h>
@@ -41,8 +42,6 @@
namespace Layout {
-class Box;
-class Container;
class LayoutState;
class LayoutTreeContent : public CanMakeWeakPtr<LayoutTreeContent> {
@@ -55,7 +54,12 @@
Container& rootLayoutBox() { return *m_rootLayoutBox; }
const RenderBox& rootRenderer() const { return m_rootRenderer; }
- void addBox(std::unique_ptr<Box> box) { m_boxes.add(WTFMove(box)); }
+ void addBox(std::unique_ptr<Box> box)
+ {
+ ASSERT(!box->isContainer());
+ m_boxes.add(WTFMove(box));
+ }
+ void addContainer(std::unique_ptr<Container> container) { m_containers.add(WTFMove(container)); }
Box* layoutBoxForRenderer(const RenderObject& renderer) { return m_renderObjectToLayoutBox.get(&renderer); }
const Box* layoutBoxForRenderer(const RenderObject& renderer) const { return m_renderObjectToLayoutBox.get(&renderer); }
@@ -68,6 +72,7 @@
const RenderBox& m_rootRenderer;
std::unique_ptr<Container> m_rootLayoutBox;
HashSet<std::unique_ptr<Box>> m_boxes;
+ HashSet<std::unique_ptr<Container>> m_containers;
HashMap<const RenderObject*, Box*> m_renderObjectToLayoutBox;
HashMap<const Box*, const RenderObject*> m_layoutBoxToRenderObject;
@@ -76,7 +81,6 @@
class TreeBuilder {
public:
static std::unique_ptr<Layout::LayoutTreeContent> buildLayoutTree(const RenderView&);
- static std::unique_ptr<Layout::LayoutTreeContent> buildLayoutTreeForIntegration(const RenderBlockFlow&);
private:
TreeBuilder(LayoutTreeContent&);
@@ -84,8 +88,12 @@
void buildTree();
void buildSubTree(const RenderElement& parentRenderer, Container& parentContainer);
void buildTableStructure(const RenderTable& tableRenderer, Container& tableWrapperBox);
- std::unique_ptr<Box> createLayoutBox(const Container& parentContainer, const RenderObject& childRenderer);
+ Box* createLayoutBox(const Container& parentContainer, const RenderObject& childRenderer);
+ Box& createBox(Optional<Box::ElementAttributes>, RenderStyle&&);
+ Box& createTextBox(TextContext&&, RenderStyle&&);
+ Container& createContainer(Optional<Box::ElementAttributes>, RenderStyle&&);
+
LayoutTreeContent& m_layoutTreeContent;
};