From 69d8b0290ea825a1cc6912c16696a20674f0d3dd Mon Sep 17 00:00:00 2001 From: "zalan@apple.com" Date: Thu, 3 May 2018 03:19:33 +0000 Subject: [PATCH] [LFC] Implement LayoutContext::createDisplayBox https://bugs.webkit.org/show_bug.cgi?id=185158 Reviewed by Antti Koivisto. Now compute*() functions take both the const layout and the corresponding non-const display boxes. Display boxes are owned by the LayoutContext and they don't form a tree structure (only implicitly through the layout tree). (This might need to change in the future if we decide to arrange them in some sort of painting order) * layout/FloatingContext.cpp: (WebCore::Layout::FloatingContext::computePosition): * layout/FloatingContext.h: * layout/FormattingContext.cpp: (WebCore::Layout::FormattingContext::computeStaticPosition const): (WebCore::Layout::FormattingContext::computeInFlowPositionedPosition const): (WebCore::Layout::FormattingContext::computeOutOfFlowPosition const): (WebCore::Layout::FormattingContext::computeWidth const): (WebCore::Layout::FormattingContext::computeHeight const): (WebCore::Layout::FormattingContext::computeOutOfFlowWidth const): (WebCore::Layout::FormattingContext::computeFloatingWidth const): (WebCore::Layout::FormattingContext::computeOutOfFlowHeight const): (WebCore::Layout::FormattingContext::computeFloatingHeight const): * layout/FormattingContext.h: * layout/LayoutContext.cpp: (WebCore::Layout::LayoutContext::createDisplayBox): * layout/LayoutContext.h: (WebCore::Layout::LayoutContext::displayBoxForLayoutBox const): * layout/blockformatting/BlockFormattingContext.cpp: (WebCore::Layout::BlockFormattingContext::layout const): (WebCore::Layout::BlockFormattingContext::computeStaticPosition const): (WebCore::Layout::BlockFormattingContext::computeInFlowWidth const): (WebCore::Layout::BlockFormattingContext::computeInFlowHeight const): * layout/blockformatting/BlockFormattingContext.h: * layout/displaytree/DisplayBox.h: (WebCore::Display::Box::parent const): Deleted. (WebCore::Display::Box::nextSibling const): Deleted. (WebCore::Display::Box::previousSibling const): Deleted. (WebCore::Display::Box::firstChild const): Deleted. (WebCore::Display::Box::lastChild const): Deleted. (WebCore::Display::Box::setParent): Deleted. (WebCore::Display::Box::setNextSibling): Deleted. (WebCore::Display::Box::setPreviousSibling): Deleted. (WebCore::Display::Box::setFirstChild): Deleted. (WebCore::Display::Box::setLastChild): Deleted. (): Deleted. * layout/inlineformatting/InlineFormattingContext.cpp: (WebCore::Layout::InlineFormattingContext::computeInFlowWidth const): (WebCore::Layout::InlineFormattingContext::computeInFlowHeight const): * layout/inlineformatting/InlineFormattingContext.h: git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231293 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebCore/ChangeLog | 52 +++++++++++++++++++ Source/WebCore/layout/FloatingContext.cpp | 2 +- Source/WebCore/layout/FloatingContext.h | 6 ++- Source/WebCore/layout/FormattingContext.cpp | 30 +++++------ Source/WebCore/layout/FormattingContext.h | 32 ++++++++---- Source/WebCore/layout/LayoutContext.cpp | 9 ++++ Source/WebCore/layout/LayoutContext.h | 5 +- .../BlockFormattingContext.cpp | 36 ++++++++----- .../blockformatting/BlockFormattingContext.h | 6 +-- .../WebCore/layout/displaytree/DisplayBox.h | 26 +++------- .../InlineFormattingContext.cpp | 4 +- .../InlineFormattingContext.h | 4 +- 12 files changed, 141 insertions(+), 71 deletions(-) diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 351a8421c355..31c522049281 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,55 @@ +2018-05-02 Zalan Bujtas + + [LFC] Implement LayoutContext::createDisplayBox + https://bugs.webkit.org/show_bug.cgi?id=185158 + + Reviewed by Antti Koivisto. + + Now compute*() functions take both the const layout and the corresponding non-const display boxes. + Display boxes are owned by the LayoutContext and they don't form a tree structure (only implicitly through the layout tree). + (This might need to change in the future if we decide to arrange them in some sort of painting order) + + * layout/FloatingContext.cpp: + (WebCore::Layout::FloatingContext::computePosition): + * layout/FloatingContext.h: + * layout/FormattingContext.cpp: + (WebCore::Layout::FormattingContext::computeStaticPosition const): + (WebCore::Layout::FormattingContext::computeInFlowPositionedPosition const): + (WebCore::Layout::FormattingContext::computeOutOfFlowPosition const): + (WebCore::Layout::FormattingContext::computeWidth const): + (WebCore::Layout::FormattingContext::computeHeight const): + (WebCore::Layout::FormattingContext::computeOutOfFlowWidth const): + (WebCore::Layout::FormattingContext::computeFloatingWidth const): + (WebCore::Layout::FormattingContext::computeOutOfFlowHeight const): + (WebCore::Layout::FormattingContext::computeFloatingHeight const): + * layout/FormattingContext.h: + * layout/LayoutContext.cpp: + (WebCore::Layout::LayoutContext::createDisplayBox): + * layout/LayoutContext.h: + (WebCore::Layout::LayoutContext::displayBoxForLayoutBox const): + * layout/blockformatting/BlockFormattingContext.cpp: + (WebCore::Layout::BlockFormattingContext::layout const): + (WebCore::Layout::BlockFormattingContext::computeStaticPosition const): + (WebCore::Layout::BlockFormattingContext::computeInFlowWidth const): + (WebCore::Layout::BlockFormattingContext::computeInFlowHeight const): + * layout/blockformatting/BlockFormattingContext.h: + * layout/displaytree/DisplayBox.h: + (WebCore::Display::Box::parent const): Deleted. + (WebCore::Display::Box::nextSibling const): Deleted. + (WebCore::Display::Box::previousSibling const): Deleted. + (WebCore::Display::Box::firstChild const): Deleted. + (WebCore::Display::Box::lastChild const): Deleted. + (WebCore::Display::Box::setParent): Deleted. + (WebCore::Display::Box::setNextSibling): Deleted. + (WebCore::Display::Box::setPreviousSibling): Deleted. + (WebCore::Display::Box::setFirstChild): Deleted. + (WebCore::Display::Box::setLastChild): Deleted. + (): Deleted. + * layout/inlineformatting/InlineFormattingContext.cpp: + (WebCore::Layout::InlineFormattingContext::computeInFlowWidth const): + (WebCore::Layout::InlineFormattingContext::computeInFlowHeight const): + * layout/inlineformatting/InlineFormattingContext.h: + 2018-05-02 Said Abou-Hallawa Hiding then showing an of type image makes the underlaying image disappear diff --git a/Source/WebCore/layout/FloatingContext.cpp b/Source/WebCore/layout/FloatingContext.cpp index f7430cda44b4..9ebfb2df25e4 100644 --- a/Source/WebCore/layout/FloatingContext.cpp +++ b/Source/WebCore/layout/FloatingContext.cpp @@ -39,7 +39,7 @@ FloatingContext::FloatingContext(FloatingState&) { } -void FloatingContext::computePosition(const Box&) +void FloatingContext::computePosition(const Box&, Display::Box&) { } diff --git a/Source/WebCore/layout/FloatingContext.h b/Source/WebCore/layout/FloatingContext.h index b45b944efdbd..41c31f1b5109 100644 --- a/Source/WebCore/layout/FloatingContext.h +++ b/Source/WebCore/layout/FloatingContext.h @@ -32,6 +32,10 @@ namespace WebCore { +namespace Display { +class Box; +} + namespace Layout { class Box; @@ -44,7 +48,7 @@ class FloatingContext { public: FloatingContext(FloatingState&); - void computePosition(const Box&); + void computePosition(const Box&, Display::Box&); LayoutUnit left(LayoutUnit verticalPosition); LayoutUnit right(LayoutUnit verticalPosition); LayoutUnit bottom(); diff --git a/Source/WebCore/layout/FormattingContext.cpp b/Source/WebCore/layout/FormattingContext.cpp index a81fa536178a..63f1b500b352 100644 --- a/Source/WebCore/layout/FormattingContext.cpp +++ b/Source/WebCore/layout/FormattingContext.cpp @@ -46,49 +46,49 @@ FormattingContext::~FormattingContext() { } -void FormattingContext::computeStaticPosition(const Box&) const +void FormattingContext::computeStaticPosition(const Box&, Display::Box&) const { } -void FormattingContext::computeInFlowPositionedPosition(const Box&) const +void FormattingContext::computeInFlowPositionedPosition(const Box&, Display::Box&) const { } -void FormattingContext::computeOutOfFlowPosition(const Box&) const +void FormattingContext::computeOutOfFlowPosition(const Box&, Display::Box&) const { } -void FormattingContext::computeWidth(const Box& layoutBox) const +void FormattingContext::computeWidth(const Box& layoutBox, Display::Box& displayBox) const { if (layoutBox.isOutOfFlowPositioned()) - return computeOutOfFlowWidth(layoutBox); + return computeOutOfFlowWidth(layoutBox, displayBox); if (layoutBox.isFloatingPositioned()) - return computeFloatingWidth(layoutBox); - return computeInFlowWidth(layoutBox); + return computeFloatingWidth(layoutBox, displayBox); + return computeInFlowWidth(layoutBox, displayBox); } -void FormattingContext::computeHeight(const Box& layoutBox) const +void FormattingContext::computeHeight(const Box& layoutBox, Display::Box& displayBox) const { if (layoutBox.isOutOfFlowPositioned()) - return computeOutOfFlowHeight(layoutBox); + return computeOutOfFlowHeight(layoutBox, displayBox); if (layoutBox.isFloatingPositioned()) - return computeFloatingHeight(layoutBox); - return computeInFlowHeight(layoutBox); + return computeFloatingHeight(layoutBox, displayBox); + return computeInFlowHeight(layoutBox, displayBox); } -void FormattingContext::computeOutOfFlowWidth(const Box&) const +void FormattingContext::computeOutOfFlowWidth(const Box&, Display::Box&) const { } -void FormattingContext::computeFloatingWidth(const Box&) const +void FormattingContext::computeFloatingWidth(const Box&, Display::Box&) const { } -void FormattingContext::computeOutOfFlowHeight(const Box&) const +void FormattingContext::computeOutOfFlowHeight(const Box&, Display::Box&) const { } -void FormattingContext::computeFloatingHeight(const Box&) const +void FormattingContext::computeFloatingHeight(const Box&, Display::Box&) const { } diff --git a/Source/WebCore/layout/FormattingContext.h b/Source/WebCore/layout/FormattingContext.h index 3a4f5704e15e..5379ebdb3bad 100644 --- a/Source/WebCore/layout/FormattingContext.h +++ b/Source/WebCore/layout/FormattingContext.h @@ -34,6 +34,10 @@ namespace WebCore { +namespace Display { +class Box; +} + namespace Layout { class Box; @@ -52,23 +56,29 @@ public: virtual Ref createOrFindFloatingState() const = 0; protected: + struct LayoutPair { + const Box& layoutBox; + Display::Box& displayBox; + }; + using LayoutQueue = Vector>; + const Box& root() const { return *m_root; } const LayoutContext& layoutContext() const { return m_layoutContext; } - virtual void computeStaticPosition(const Box&) const; - virtual void computeInFlowPositionedPosition(const Box&) const; - virtual void computeOutOfFlowPosition(const Box&) const; + virtual void computeStaticPosition(const Box&, Display::Box&) const; + virtual void computeInFlowPositionedPosition(const Box&, Display::Box&) const; + virtual void computeOutOfFlowPosition(const Box&, Display::Box&) const; - virtual void computeWidth(const Box&) const; - virtual void computeHeight(const Box&) const; + virtual void computeWidth(const Box&, Display::Box&) const; + virtual void computeHeight(const Box&, Display::Box&) const; - virtual void computeOutOfFlowWidth(const Box&) const; - virtual void computeFloatingWidth(const Box&) const; - virtual void computeInFlowWidth(const Box&) const = 0; + virtual void computeOutOfFlowWidth(const Box&, Display::Box&) const; + virtual void computeFloatingWidth(const Box&, Display::Box&) const; + virtual void computeInFlowWidth(const Box&, Display::Box&) const = 0; - virtual void computeOutOfFlowHeight(const Box&) const; - virtual void computeFloatingHeight(const Box&) const; - virtual void computeInFlowHeight(const Box&) const = 0; + virtual void computeOutOfFlowHeight(const Box&, Display::Box&) const; + virtual void computeFloatingHeight(const Box&, Display::Box&) const; + virtual void computeInFlowHeight(const Box&, Display::Box&) const = 0; virtual LayoutUnit marginTop(const Box&) const; virtual LayoutUnit marginLeft(const Box&) const; diff --git a/Source/WebCore/layout/LayoutContext.cpp b/Source/WebCore/layout/LayoutContext.cpp index 9c2d4b71f901..9e98ae7f61a2 100644 --- a/Source/WebCore/layout/LayoutContext.cpp +++ b/Source/WebCore/layout/LayoutContext.cpp @@ -30,6 +30,7 @@ #include "BlockFormattingContext.h" #include "BlockFormattingState.h" +#include "DisplayBox.h" #include "InlineFormattingContext.h" #include "InlineFormattingState.h" #include "LayoutBox.h" @@ -53,6 +54,14 @@ void LayoutContext::updateLayout() context->layout(*this, state); } +Display::Box& LayoutContext::createDisplayBox(const Box& layoutBox) +{ + std::unique_ptr displayBox(new Display::Box()); + auto* displayBoxPtr = displayBox.get(); + m_layoutToDisplayBox.add(&layoutBox, WTFMove(displayBox)); + return *displayBoxPtr; +} + FormattingState& LayoutContext::formattingStateForBox(const Box& layoutBox) const { auto& root = layoutBox.formattingContextRoot(); diff --git a/Source/WebCore/layout/LayoutContext.h b/Source/WebCore/layout/LayoutContext.h index a99b15f7f894..77efa06a5d30 100644 --- a/Source/WebCore/layout/LayoutContext.h +++ b/Source/WebCore/layout/LayoutContext.h @@ -54,8 +54,8 @@ public: void updateLayout(); - void addDisplayBox(const Box&, Display::Box&); - Display::Box* displayBox(const Box&) const; + Display::Box& createDisplayBox(const Box&); + Display::Box* displayBoxForLayoutBox(const Box& layoutBox) const { return m_layoutToDisplayBox.get(&layoutBox); } void markNeedsLayout(const Box&, StyleDiff); bool needsLayout(const Box&) const; @@ -67,6 +67,7 @@ public: private: WeakPtr m_root; HashMap> m_formattingStates; + HashMap> m_layoutToDisplayBox; }; } diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp index 080942667ff5..237b7320b5f0 100644 --- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp +++ b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp @@ -29,6 +29,7 @@ #if ENABLE(LAYOUT_FORMATTING_CONTEXT) #include "BlockFormattingState.h" +#include "DisplayBox.h" #include "FloatingContext.h" #include "FloatingState.h" #include "LayoutBox.h" @@ -55,12 +56,12 @@ void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingStat if (!is(root())) return; auto& formattingRoot = downcast(root()); - Vector layoutQueue; + LayoutQueue layoutQueue; FloatingContext floatingContext(formattingState.floatingState()); // This is a post-order tree traversal layout. // The root container layout is done in the formatting context it lives in, not that one it creates, so let's start with the first child. - if (formattingRoot.hasInFlowOrFloatingChild()) - layoutQueue.append(formattingRoot.firstInFlowOrFloatingChild()); + if (auto* firstChild = formattingRoot.firstInFlowOrFloatingChild()) + layoutQueue.append(std::make_unique(LayoutPair {*firstChild, layoutContext.createDisplayBox(*firstChild)})); // 1. Go all the way down to the leaf node // 2. Compute static position and width as we traverse down // 3. As we climb back on the tree, compute height and finialize position @@ -68,9 +69,12 @@ void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingStat while (!layoutQueue.isEmpty()) { // Traverse down on the descendants and compute width/static position until we find a leaf node. while (true) { - auto& layoutBox = *layoutQueue.last(); - computeWidth(layoutBox); - computeStaticPosition(layoutBox); + auto& layoutPair = *layoutQueue.last(); + auto& layoutBox = layoutPair.layoutBox; + auto& displayBox = layoutPair.displayBox; + + computeWidth(layoutBox, displayBox); + computeStaticPosition(layoutBox, layoutPair.displayBox); if (layoutBox.establishesFormattingContext()) { auto formattingContext = layoutContext.formattingContext(layoutBox); formattingContext->layout(layoutContext, layoutContext.establishedFormattingState(layoutBox, *formattingContext)); @@ -78,23 +82,27 @@ void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingStat } if (!is(layoutBox) || !downcast(layoutBox).hasInFlowOrFloatingChild()) break; - layoutQueue.append(downcast(layoutBox).firstInFlowOrFloatingChild()); + auto& firstChild = *downcast(layoutBox).firstInFlowOrFloatingChild(); + layoutQueue.append(std::make_unique(LayoutPair {firstChild, layoutContext.createDisplayBox(firstChild)})); } // Climb back on the ancestors and compute height/final position. while (!layoutQueue.isEmpty()) { // All inflow descendants (if there are any) are laid out by now. Let's compute the box's height. - auto& layoutBox = *layoutQueue.takeLast(); - computeHeight(layoutBox); + auto layoutPair = layoutQueue.takeLast(); + auto& layoutBox = layoutPair->layoutBox; + auto& displayBox = layoutPair->displayBox; + + computeHeight(layoutBox, displayBox); // Adjust position now that we have all the previous floats placed in this context -if needed. - floatingContext.computePosition(layoutBox); + floatingContext.computePosition(layoutBox, displayBox); if (!is(layoutBox)) continue; auto& container = downcast(layoutBox); // Move in-flow positioned children to their final position. placeInFlowPositionedChildren(container); if (auto* nextSibling = container.nextInFlowOrFloatingSibling()) { - layoutQueue.append(nextSibling); + layoutQueue.append(std::make_unique(LayoutPair {*nextSibling, layoutContext.createDisplayBox(*nextSibling)})); break; } } @@ -116,15 +124,15 @@ Ref BlockFormattingContext::createOrFindFloatingState() const return FloatingState::create(); } -void BlockFormattingContext::computeStaticPosition(const Box&) const +void BlockFormattingContext::computeStaticPosition(const Box&, Display::Box&) const { } -void BlockFormattingContext::computeInFlowWidth(const Box&) const +void BlockFormattingContext::computeInFlowWidth(const Box&, Display::Box&) const { } -void BlockFormattingContext::computeInFlowHeight(const Box&) const +void BlockFormattingContext::computeInFlowHeight(const Box&, Display::Box&) const { } diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContext.h b/Source/WebCore/layout/blockformatting/BlockFormattingContext.h index efbac24373a5..03cff356364e 100644 --- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.h +++ b/Source/WebCore/layout/blockformatting/BlockFormattingContext.h @@ -50,9 +50,9 @@ public: Ref createOrFindFloatingState() const override; protected: - void computeStaticPosition(const Box&) const override; - void computeInFlowWidth(const Box&) const override; - void computeInFlowHeight(const Box&) const override; + void computeStaticPosition(const Box&, Display::Box&) const override; + void computeInFlowWidth(const Box&, Display::Box&) const override; + void computeInFlowHeight(const Box&, Display::Box&) const override; LayoutUnit marginTop(const Box&) const override; LayoutUnit marginBottom(const Box&) const override; diff --git a/Source/WebCore/layout/displaytree/DisplayBox.h b/Source/WebCore/layout/displaytree/DisplayBox.h index e9d429f8ac99..73ea630599be 100644 --- a/Source/WebCore/layout/displaytree/DisplayBox.h +++ b/Source/WebCore/layout/displaytree/DisplayBox.h @@ -33,12 +33,17 @@ #include namespace WebCore { + +namespace Layout { +class LayoutContext; +} + namespace Display { class Box { WTF_MAKE_ISO_ALLOCATED(Box); public: - friend class FormattingContext; + friend class Layout::LayoutContext; ~Box(); @@ -66,12 +71,6 @@ public: LayoutRect paddingBox() const; LayoutRect contentBox() const; - const Box* parent() const { return m_parent; } - const Box* nextSibling() const { return m_parent; } - const Box* previousSibling() const { return m_parent; } - const Box* firstChild() const { return m_firstChild; } - const Box* lastChild() const { return m_lastChild; } - private: Box(); @@ -98,12 +97,6 @@ private: void setPaddingBottom(LayoutUnit paddingBottom) { m_paddingBottom = paddingBottom; } void setPaddingRight(LayoutUnit paddingRight) { m_paddingRight = paddingRight; } - void setParent(Box& parent) { m_parent = &parent; } - void setNextSibling(Box& nextSibling) { m_nextSibling = &nextSibling; } - void setPreviousSibling(Box& previousSibling) { m_previousSibling = &previousSibling; } - void setFirstChild(Box& firstChild) { m_firstChild = &firstChild; } - void setLastChild(Box& lastChild) { m_lastChild = &lastChild; } - LayoutRect m_rect; LayoutUnit m_marginTop; LayoutUnit m_marginLeft; @@ -119,13 +112,6 @@ private: LayoutUnit m_paddingLeft; LayoutUnit m_paddingBottom; LayoutUnit m_paddingRight; - - const Box* m_parent { nullptr }; - const Box* m_nextSibling { nullptr }; - const Box* m_previousSibling { nullptr }; - const Box* m_firstChild { nullptr }; - const Box* m_lastChild { nullptr }; - }; } diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp index 50aa1c904f97..f934f68ab536 100644 --- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp +++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp @@ -66,11 +66,11 @@ Ref InlineFormattingContext::createOrFindFloatingState() const return formattingState.floatingState(); } -void InlineFormattingContext::computeInFlowWidth(const Box&) const +void InlineFormattingContext::computeInFlowWidth(const Box&, Display::Box&) const { } -void InlineFormattingContext::computeInFlowHeight(const Box&) const +void InlineFormattingContext::computeInFlowHeight(const Box&, Display::Box&) const { } diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h index aa5c379d79a1..9760b8d05501 100644 --- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h +++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h @@ -48,8 +48,8 @@ public: Ref createOrFindFloatingState() const override; private: - void computeInFlowWidth(const Box&) const override; - void computeInFlowHeight(const Box&) const override; + void computeInFlowWidth(const Box&, Display::Box&) const override; + void computeInFlowHeight(const Box&, Display::Box&) const override; }; -- 2.36.0