WebKit Bugzilla
Attachment 339003 Details for
Bug 185024
: [LFC] Implement BlockFormattingContext::layout logic and its dependencies
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185024-20180427103925.patch (text/plain), 13.34 KB, created by
zalan
on 2018-04-27 10:39:25 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
zalan
Created:
2018-04-27 10:39:25 PDT
Size:
13.34 KB
patch
obsolete
>Subversion Revision: 231096 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 98241705f3f50ac9a1f3405d50d9c394ecb86a22..f24a1693d30400a6df4cba5f8a0430a5dbfd15ad 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,43 @@ >+2018-04-27 Zalan Bujtas <zalan@apple.com> >+ >+ [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 Zalan Bujtas <zalan@apple.com> > > [LFC] Formatting contexts should create floating states. >diff --git a/Source/WebCore/layout/FloatingContext.cpp b/Source/WebCore/layout/FloatingContext.cpp >index 92872aa3a749c00d52efd6a18390d1a735aef8a1..f7430cda44b495894e6cb138376ff3f409a28e6b 100644 >--- a/Source/WebCore/layout/FloatingContext.cpp >+++ b/Source/WebCore/layout/FloatingContext.cpp >@@ -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 >diff --git a/Source/WebCore/layout/FormattingContext.cpp b/Source/WebCore/layout/FormattingContext.cpp >index dca0475ea58a7e8cf3288659ce551b16553b0c53..9840a3fb240e10438d57bfef08fcc5a360a3e915 100644 >--- a/Source/WebCore/layout/FormattingContext.cpp >+++ b/Source/WebCore/layout/FormattingContext.cpp >@@ -85,6 +85,14 @@ LayoutUnit FormattingContext::marginRight(const Box&) const > return 0; > } > >+void FormattingContext::placeInFlowPositionedChildren(const Container&) const >+{ >+} >+ >+void FormattingContext::layoutOutOfFlowDescendants() const >+{ >+} >+ > } > } > #endif >diff --git a/Source/WebCore/layout/FormattingContext.h b/Source/WebCore/layout/FormattingContext.h >index bde31e212262915681ca7046050a08b0e404e760..c6c146143df5b7385e7a9e447495cf21ede6526a 100644 >--- a/Source/WebCore/layout/FormattingContext.h >+++ b/Source/WebCore/layout/FormattingContext.h >@@ -37,6 +37,7 @@ namespace WebCore { > namespace Layout { > > class Box; >+class Container; > class FormattingState; > class LayoutContext; > >@@ -46,7 +47,7 @@ public: > 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 @@ protected: > 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; >diff --git a/Source/WebCore/layout/LayoutContext.cpp b/Source/WebCore/layout/LayoutContext.cpp >index 4c9b6fd092a92efd8f88a2e005f68df486f2bc7d..9c2d4b71f9015956c79b04e87cb9870727f29569 100644 >--- a/Source/WebCore/layout/LayoutContext.cpp >+++ b/Source/WebCore/layout/LayoutContext.cpp >@@ -50,7 +50,7 @@ void LayoutContext::updateLayout() > { > 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 @@ FormattingState& LayoutContext::formattingStateForBox(const Box& layoutBox) cons > 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()); >diff --git a/Source/WebCore/layout/LayoutContext.h b/Source/WebCore/layout/LayoutContext.h >index 6589e51940b35484661ec2e7ab56bfb3035411aa..5768bd2fe465ca2337abcd5f029bcffc1c28f4a4 100644 >--- a/Source/WebCore/layout/LayoutContext.h >+++ b/Source/WebCore/layout/LayoutContext.h >@@ -61,11 +61,10 @@ public: > bool needsLayout(const Box&) const; > > FormattingState& formattingStateForBox(const Box&) const; >- >-private: >- FormattingState& establishedFormattingState(Box& formattingContextRoot, const FormattingContext&); >+ FormattingState& establishedFormattingState(const Box& formattingContextRoot, const FormattingContext&); > std::unique_ptr<FormattingContext> formattingContext(const Box& formattingContextRoot); > >+private: > WeakPtr<Box> m_root; > HashMap<const Box*, std::unique_ptr<FormattingState>> m_formattingStates; > }; >diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >index e80545b9f036b290aa67531fb15d3de46b5697ce..b57f1e7df247e579b17b9077e59c402bb6a5ad64 100644 >--- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >@@ -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 @@ BlockFormattingContext::BlockFormattingContext(const Box& formattingContextRoot, > { > } > >-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 >diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContext.h b/Source/WebCore/layout/blockformatting/BlockFormattingContext.h >index 026398ba275d3b613b2473d32f9bdc0b7c0cef55..aade5a6556a36f4ffc56ff1b52fa660777f74aea 100644 >--- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.h >+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContext.h >@@ -45,7 +45,7 @@ class BlockFormattingContext : public FormattingContext { > 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; > >diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp >index 22a4807b6dfeb9d5c9b77eb0ed04e79bf50a12db..2235266b707a20b166405219d9cb64c3eae256aa 100644 >--- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp >+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp >@@ -44,7 +44,7 @@ InlineFormattingContext::InlineFormattingContext(const Box& formattingContextRoo > { > } > >-void InlineFormattingContext::layout(FormattingState&) >+void InlineFormattingContext::layout(LayoutContext&, FormattingState&) const > { > } > >diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h >index 36580e1db4403e3645f771c3b1190585890309fb..f2587f40fc6de60da3a6f7aac05f83f46a7c5436 100644 >--- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h >+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h >@@ -43,7 +43,7 @@ class InlineFormattingContext : public FormattingContext { > 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; > };
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185024
:
338856
|
338999
| 339003