Title: [231108] trunk/Source/WebCore
Revision
231108
Author
[email protected]
Date
2018-04-27 11:17:46 -0700 (Fri, 27 Apr 2018)

Log Message

[LFC] Implement BlockFormattingContext::layout logic and its dependencies
https://bugs.webkit.org/show_bug.cgi?id=185024

Reviewed by Antti Koivisto.

This patch implements the logic for block formatting context according to
https://www.w3.org/TR/CSS22/visuren.html#block-formatting

1. Traverse the tree iteratively (in post-order fashion) and compute the width/static position for the containers as
we visit the descendant nodes until we hit a leaf node.
2. Compute the position/geometry of the leaf node and move over to its sibling(s).
3. Finalize the container's height/final position as we climb back on the tree.
4. Run layout on the out-of-flow descendants.

Note that subtrees with a formatting context root need to be laid out completely before moving on to the next box.
The formatting root box is laid out in the formatting context it lives in, however its descendants get laid out
in a separate formatting context (excluding out-of-flow boxes that don't belong to the root).

* layout/FloatingContext.cpp:
(WebCore::Layout::FloatingContext::FloatingContext):
(WebCore::Layout::FloatingContext::computePosition):
* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::placeInFlowPositionedChildren const):
(WebCore::Layout::FormattingContext::layoutOutOfFlowDescendants const):
* layout/FormattingContext.h:
* layout/LayoutContext.cpp:
(WebCore::Layout::LayoutContext::updateLayout):
(WebCore::Layout::LayoutContext::establishedFormattingState):
* layout/LayoutContext.h:
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::layout const):
(WebCore::Layout::BlockFormattingContext::layout): Deleted.
* layout/blockformatting/BlockFormattingContext.h:
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::layout const):
(WebCore::Layout::InlineFormattingContext::layout): Deleted.
* layout/inlineformatting/InlineFormattingContext.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (231107 => 231108)


--- trunk/Source/WebCore/ChangeLog	2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/ChangeLog	2018-04-27 18:17:46 UTC (rev 231108)
@@ -1,3 +1,43 @@
+2018-04-27  Zalan Bujtas  <[email protected]>
+
+        [LFC] Implement BlockFormattingContext::layout logic and its dependencies
+        https://bugs.webkit.org/show_bug.cgi?id=185024
+
+        Reviewed by Antti Koivisto.
+
+        This patch implements the logic for block formatting context according to
+        https://www.w3.org/TR/CSS22/visuren.html#block-formatting
+
+        1. Traverse the tree iteratively (in post-order fashion) and compute the width/static position for the containers as
+        we visit the descendant nodes until we hit a leaf node.
+        2. Compute the position/geometry of the leaf node and move over to its sibling(s).
+        3. Finalize the container's height/final position as we climb back on the tree.
+        4. Run layout on the out-of-flow descendants.  
+
+        Note that subtrees with a formatting context root need to be laid out completely before moving on to the next box.
+        The formatting root box is laid out in the formatting context it lives in, however its descendants get laid out
+        in a separate formatting context (excluding out-of-flow boxes that don't belong to the root). 
+
+        * layout/FloatingContext.cpp:
+        (WebCore::Layout::FloatingContext::FloatingContext):
+        (WebCore::Layout::FloatingContext::computePosition):
+        * layout/FormattingContext.cpp:
+        (WebCore::Layout::FormattingContext::placeInFlowPositionedChildren const):
+        (WebCore::Layout::FormattingContext::layoutOutOfFlowDescendants const):
+        * layout/FormattingContext.h:
+        * layout/LayoutContext.cpp:
+        (WebCore::Layout::LayoutContext::updateLayout):
+        (WebCore::Layout::LayoutContext::establishedFormattingState):
+        * layout/LayoutContext.h:
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::layout const):
+        (WebCore::Layout::BlockFormattingContext::layout): Deleted.
+        * layout/blockformatting/BlockFormattingContext.h:
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::layout const):
+        (WebCore::Layout::InlineFormattingContext::layout): Deleted.
+        * layout/inlineformatting/InlineFormattingContext.h:
+
 2018-04-27  Youenn Fablet  <[email protected]>
 
         Use NetworkLoadChecker for XHR/fetch loads

Modified: trunk/Source/WebCore/layout/FloatingContext.cpp (231107 => 231108)


--- trunk/Source/WebCore/layout/FloatingContext.cpp	2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/FloatingContext.cpp	2018-04-27 18:17:46 UTC (rev 231108)
@@ -25,3 +25,24 @@
 
 #include "config.h"
 #include "FloatingContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(FloatingContext);
+
+FloatingContext::FloatingContext(FloatingState&)
+{
+}
+
+void FloatingContext::computePosition(const Box&)
+{
+}
+
+}
+}
+#endif

Modified: trunk/Source/WebCore/layout/FormattingContext.cpp (231107 => 231108)


--- trunk/Source/WebCore/layout/FormattingContext.cpp	2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/FormattingContext.cpp	2018-04-27 18:17:46 UTC (rev 231108)
@@ -85,6 +85,14 @@
     return 0;
 }
 
+void FormattingContext::placeInFlowPositionedChildren(const Container&) const
+{
 }
+
+void FormattingContext::layoutOutOfFlowDescendants() const
+{
 }
+
+}
+}
 #endif

Modified: trunk/Source/WebCore/layout/FormattingContext.h (231107 => 231108)


--- trunk/Source/WebCore/layout/FormattingContext.h	2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/FormattingContext.h	2018-04-27 18:17:46 UTC (rev 231108)
@@ -37,6 +37,7 @@
 namespace Layout {
 
 class Box;
+class Container;
 class FormattingState;
 class LayoutContext;
 
@@ -46,7 +47,7 @@
     FormattingContext(const Box& formattingContextRoot, LayoutContext&);
     virtual ~FormattingContext();
 
-    virtual void layout(FormattingState&) = 0;
+    virtual void layout(LayoutContext&, FormattingState&) const = 0;
     virtual std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const = 0;
     virtual Ref<FloatingState> createOrFindFloatingState() const = 0;
 
@@ -66,6 +67,9 @@
     virtual LayoutUnit marginBottom(const Box&) const;
     virtual LayoutUnit marginRight(const Box&) const;
 
+    void placeInFlowPositionedChildren(const Container&) const;
+    void layoutOutOfFlowDescendants() const;
+
 private:
     WeakPtr<Box> m_root;
     LayoutContext& m_layoutContext;

Modified: trunk/Source/WebCore/layout/LayoutContext.cpp (231107 => 231108)


--- trunk/Source/WebCore/layout/LayoutContext.cpp	2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/LayoutContext.cpp	2018-04-27 18:17:46 UTC (rev 231108)
@@ -50,7 +50,7 @@
 {
     auto context = formattingContext(*m_root);
     auto& state = establishedFormattingState(*m_root, *context);
-    context->layout(state);
+    context->layout(*this, state);
 }
 
 FormattingState& LayoutContext::formattingStateForBox(const Box& layoutBox) const
@@ -60,7 +60,7 @@
     return *m_formattingStates.get(&root);
 }
 
-FormattingState& LayoutContext::establishedFormattingState(Box& formattingContextRoot, const FormattingContext& context)
+FormattingState& LayoutContext::establishedFormattingState(const Box& formattingContextRoot, const FormattingContext& context)
 {
     return *m_formattingStates.ensure(&formattingContextRoot, [this, &context] {
         return context.createFormattingState(context.createOrFindFloatingState());

Modified: trunk/Source/WebCore/layout/LayoutContext.h (231107 => 231108)


--- trunk/Source/WebCore/layout/LayoutContext.h	2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/LayoutContext.h	2018-04-27 18:17:46 UTC (rev 231108)
@@ -61,11 +61,10 @@
     bool needsLayout(const Box&) const;
 
     FormattingState& formattingStateForBox(const Box&) const;
+    FormattingState& establishedFormattingState(const Box& formattingContextRoot, const FormattingContext&);
+    std::unique_ptr<FormattingContext> formattingContext(const Box& formattingContextRoot);
 
 private:
-    FormattingState& establishedFormattingState(Box& formattingContextRoot, const FormattingContext&);
-    std::unique_ptr<FormattingContext> formattingContext(const Box& formattingContextRoot);
-
     WeakPtr<Box> m_root;
     HashMap<const Box*, std::unique_ptr<FormattingState>> m_formattingStates;
 };

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (231107 => 231108)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2018-04-27 18:17:46 UTC (rev 231108)
@@ -29,7 +29,11 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "BlockFormattingState.h"
+#include "FloatingContext.h"
 #include "FloatingState.h"
+#include "LayoutBox.h"
+#include "LayoutContainer.h"
+#include "LayoutContext.h"
 #include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
@@ -42,8 +46,63 @@
 {
 }
 
-void BlockFormattingContext::layout(FormattingState&)
+void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingState& formattingState) const
 {
+    // 9.4.1 Block formatting contexts
+    // In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block.
+    // The vertical distance between two sibling boxes is determined by the 'margin' properties.
+    // Vertical margins between adjacent block-level boxes in a block formatting context collapse.
+    if (!is<Container>(root()))
+        return;
+    auto& formattingRoot = downcast<Container>(root());
+    Vector<const Box*> 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());
+    // 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
+    // (Any subtrees with new formatting contexts need to layout synchronously)
+    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);
+            if (layoutBox.establishesFormattingContext()) {
+                auto formattingContext = layoutContext.formattingContext(layoutBox);
+                formattingContext->layout(layoutContext, layoutContext.establishedFormattingState(layoutBox, *formattingContext));
+                break;
+            }
+            if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowOrFloatingChild())
+                break;
+            layoutQueue.append(downcast<Container>(layoutBox).firstInFlowOrFloatingChild());
+        }
+
+        // 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);
+            // Adjust position now that we have all the previous floats placed in this context -if needed.
+            floatingContext.computePosition(layoutBox);
+            if (!is<Container>(layoutBox))
+                continue;
+            auto& container = downcast<Container>(layoutBox);
+            // Move in-flow positioned children to their final position.
+            placeInFlowPositionedChildren(container);
+            if (auto* nextSibling = container.nextInFlowOrFloatingSibling()) {
+                layoutQueue.append(nextSibling);
+                break;
+            }
+        }
+    }
+    // Place the inflow positioned children.
+    placeInFlowPositionedChildren(formattingRoot);
+    // And take care of out-of-flow boxes as the final step.
+    layoutOutOfFlowDescendants();
 }
 
 std::unique_ptr<FormattingState> BlockFormattingContext::createFormattingState(Ref<FloatingState>&& floatingState) const

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h (231107 => 231108)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2018-04-27 18:17:46 UTC (rev 231108)
@@ -45,7 +45,7 @@
 public:
     BlockFormattingContext(const Box& formattingContextRoot, LayoutContext&);
 
-    void layout(FormattingState&) override;
+    void layout(LayoutContext&, FormattingState&) const override;
     std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const override;
     Ref<FloatingState> createOrFindFloatingState() const override;
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (231107 => 231108)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2018-04-27 18:17:46 UTC (rev 231108)
@@ -44,7 +44,7 @@
 {
 }
 
-void InlineFormattingContext::layout(FormattingState&)
+void InlineFormattingContext::layout(LayoutContext&, FormattingState&) const
 {
 }
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (231107 => 231108)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2018-04-27 18:10:18 UTC (rev 231107)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2018-04-27 18:17:46 UTC (rev 231108)
@@ -43,7 +43,7 @@
 public:
     InlineFormattingContext(const Box& formattingContextRoot, LayoutContext&);
 
-    void layout(FormattingState&) override;
+    void layout(LayoutContext&, FormattingState&) const override;
     std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const override;
     Ref<FloatingState> createOrFindFloatingState() const override;
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to