Title: [231642] trunk/Source/WebCore
Revision
231642
Author
[email protected]
Date
2018-05-10 09:46:54 -0700 (Thu, 10 May 2018)

Log Message

[LFC] Implement height computation for non-replaced inflow elements.
https://bugs.webkit.org/show_bug.cgi?id=185474

Reviewed by Antti Koivisto.

Initial implementation. Does not cover all the cases.

* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::computeHeight const):
* layout/FormattingContext.h:
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::layout const):
(WebCore::Layout::BlockFormattingContext::computeInFlowHeight const):
(WebCore::Layout::BlockFormattingContext::computeInFlowNonReplacedHeight const):
* layout/blockformatting/BlockFormattingContext.h:
* layout/blockformatting/BlockMarginCollapse.cpp:
(WebCore::Layout::collapsedMarginBottomFromLastChild):
(WebCore::Layout::BlockMarginCollapse::isMarginBottomCollapsedWithParent):
(WebCore::Layout::BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom):
(WebCore::Layout::isMarginBottomCollapsedWithParent): Deleted.
* layout/blockformatting/BlockMarginCollapse.h:
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::computeInFlowHeight const):
* layout/inlineformatting/InlineFormattingContext.h:
* layout/layouttree/LayoutBox.cpp:
(WebCore::Layout::Box::isReplaced const):
* layout/layouttree/LayoutBox.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (231641 => 231642)


--- trunk/Source/WebCore/ChangeLog	2018-05-10 16:16:11 UTC (rev 231641)
+++ trunk/Source/WebCore/ChangeLog	2018-05-10 16:46:54 UTC (rev 231642)
@@ -1,3 +1,33 @@
+2018-05-10  Zalan Bujtas  <[email protected]>
+
+        [LFC] Implement height computation for non-replaced inflow elements.
+        https://bugs.webkit.org/show_bug.cgi?id=185474
+
+        Reviewed by Antti Koivisto.
+
+        Initial implementation. Does not cover all the cases.
+
+        * layout/FormattingContext.cpp:
+        (WebCore::Layout::FormattingContext::computeHeight const):
+        * layout/FormattingContext.h:
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::layout const):
+        (WebCore::Layout::BlockFormattingContext::computeInFlowHeight const):
+        (WebCore::Layout::BlockFormattingContext::computeInFlowNonReplacedHeight const):
+        * layout/blockformatting/BlockFormattingContext.h:
+        * layout/blockformatting/BlockMarginCollapse.cpp:
+        (WebCore::Layout::collapsedMarginBottomFromLastChild):
+        (WebCore::Layout::BlockMarginCollapse::isMarginBottomCollapsedWithParent):
+        (WebCore::Layout::BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom):
+        (WebCore::Layout::isMarginBottomCollapsedWithParent): Deleted.
+        * layout/blockformatting/BlockMarginCollapse.h:
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::computeInFlowHeight const):
+        * layout/inlineformatting/InlineFormattingContext.h:
+        * layout/layouttree/LayoutBox.cpp:
+        (WebCore::Layout::Box::isReplaced const):
+        * layout/layouttree/LayoutBox.h:
+
 2018-05-10  Thibault Saunier  <[email protected]>
 
         [GTK] Implement ImageBuffer::toBGRAData

Modified: trunk/Source/WebCore/layout/FormattingContext.cpp (231641 => 231642)


--- trunk/Source/WebCore/layout/FormattingContext.cpp	2018-05-10 16:16:11 UTC (rev 231641)
+++ trunk/Source/WebCore/layout/FormattingContext.cpp	2018-05-10 16:46:54 UTC (rev 231642)
@@ -68,13 +68,13 @@
     return computeInFlowWidth(layoutBox, displayBox);
 }
 
-void FormattingContext::computeHeight(const Box& layoutBox, Display::Box& displayBox) const
+void FormattingContext::computeHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
 {
     if (layoutBox.isOutOfFlowPositioned())
         return computeOutOfFlowHeight(layoutBox, displayBox);
     if (layoutBox.isFloatingPositioned())
         return computeFloatingHeight(layoutBox, displayBox);
-    return computeInFlowHeight(layoutBox, displayBox);
+    return computeInFlowHeight(layoutContext, layoutBox, displayBox);
 }
 
 void FormattingContext::computeOutOfFlowWidth(const Box&, Display::Box&) const

Modified: trunk/Source/WebCore/layout/FormattingContext.h (231641 => 231642)


--- trunk/Source/WebCore/layout/FormattingContext.h	2018-05-10 16:16:11 UTC (rev 231641)
+++ trunk/Source/WebCore/layout/FormattingContext.h	2018-05-10 16:46:54 UTC (rev 231642)
@@ -69,7 +69,7 @@
     virtual void computeOutOfFlowPosition(const Box&, Display::Box&) const;
 
     virtual void computeWidth(const Box&, Display::Box&) const;
-    virtual void computeHeight(const Box&, Display::Box&) const;
+    virtual void computeHeight(LayoutContext&, const Box&, Display::Box&) const;
 
     virtual void computeOutOfFlowWidth(const Box&, Display::Box&) const;
     virtual void computeFloatingWidth(const Box&, Display::Box&) const;
@@ -77,7 +77,7 @@
 
     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 void computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const = 0;
 
     virtual LayoutUnit marginTop(const Box&) const;
     virtual LayoutUnit marginLeft(const Box&) const;

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (231641 => 231642)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2018-05-10 16:16:11 UTC (rev 231641)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2018-05-10 16:46:54 UTC (rev 231642)
@@ -94,7 +94,7 @@
             auto& layoutBox = layoutPair->layoutBox;
             auto& displayBox = layoutPair->displayBox;
 
-            computeHeight(layoutBox, displayBox);
+            computeHeight(layoutContext, layoutBox, displayBox);
             // Adjust position now that we have all the previous floats placed in this context -if needed.
             floatingContext.computePosition(layoutBox, displayBox);
             if (!is<Container>(layoutBox))
@@ -147,8 +147,13 @@
 {
 }
 
-void BlockFormattingContext::computeInFlowHeight(const Box&, Display::Box&) const
+void BlockFormattingContext::computeInFlowHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
 {
+    if (!layoutBox.isReplaced()) {
+        computeInFlowNonReplacedHeight(layoutContext, layoutBox, displayBox);
+        return;
+    }
+    ASSERT_NOT_REACHED();
 }
 
 LayoutUnit BlockFormattingContext::marginTop(const Box& layoutBox) const
@@ -161,7 +166,62 @@
     return BlockMarginCollapse::marginBottom(layoutBox);
 }
 
+void BlockFormattingContext::computeInFlowNonReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
+{
+    // https://www.w3.org/TR/CSS22/visudet.html
+    // If 'height' is 'auto', the height depends on whether the element has any block-level children and whether it has padding or borders:
+    // The element's height is the distance from its top content edge to the first applicable of the following:
+    // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
+    // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin
+    //    does not collapse with the element's bottom margin
+    // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
+    // 4. zero, otherwise
+    // Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored,
+    // and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
+    if (!layoutBox.style().logicalHeight().isAuto()) {
+        // FIXME: Only fixed values yet.
+        displayBox.setHeight(layoutBox.style().logicalHeight().value());
+        return;
+    }
+
+    if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild()) {
+        displayBox.setHeight(0);
+        return;
+    }
+
+    // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
+    if (layoutBox.establishesInlineFormattingContext()) {
+        // height = lastLineBox().bottom();
+        displayBox.setHeight(0);
+        return;
+    }
+
+    // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin...
+    auto* lastInFlowChild = downcast<Container>(layoutBox).lastInFlowChild();
+    ASSERT(lastInFlowChild);
+    if (!BlockMarginCollapse::isMarginBottomCollapsedWithParent(*lastInFlowChild)) {
+        auto* lastInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*lastInFlowChild);
+        ASSERT(lastInFlowDisplayBox);
+        displayBox.setHeight(lastInFlowDisplayBox->bottom() + lastInFlowDisplayBox->marginBottom());
+        return;
+    }
+
+    // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
+    auto* inFlowChild = lastInFlowChild;
+    while (inFlowChild && BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom(*inFlowChild))
+        inFlowChild = inFlowChild->previousInFlowSibling();
+    if (inFlowChild) {
+        auto* inFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*inFlowChild);
+        ASSERT(inFlowDisplayBox);
+        displayBox.setHeight(inFlowDisplayBox->top() + inFlowDisplayBox->borderBox().height());
+        return;
+    }
+
+    // 4. zero, otherwise
+    displayBox.setHeight(0);
 }
+
 }
+}
 
 #endif

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h (231641 => 231642)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2018-05-10 16:16:11 UTC (rev 231641)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2018-05-10 16:46:54 UTC (rev 231642)
@@ -49,10 +49,11 @@
     std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const override;
     Ref<FloatingState> createOrFindFloatingState(LayoutContext&) const override;
 
-protected:
+private:
     void computeStaticPosition(LayoutContext&, const Box&, Display::Box&) const override;
     void computeInFlowWidth(const Box&, Display::Box&) const override;
-    void computeInFlowHeight(const Box&, Display::Box&) const override;
+    void computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const override;
+    void computeInFlowNonReplacedHeight(LayoutContext&, const Box&, Display::Box&) const;
 
     LayoutUnit marginTop(const Box&) const override;
     LayoutUnit marginBottom(const Box&) const override;

Modified: trunk/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp (231641 => 231642)


--- trunk/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp	2018-05-10 16:16:11 UTC (rev 231641)
+++ trunk/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp	2018-05-10 16:46:54 UTC (rev 231642)
@@ -114,42 +114,6 @@
     return true;
 }
 
-static bool isMarginBottomCollapsedWithParent(const Box& layoutBox)
-{
-    // last inflow box to parent.
-    // https://www.w3.org/TR/CSS21/box.html#collapsing-margins
-    if (layoutBox.isAnonymous())
-        return false;
-
-    if (layoutBox.isFloatingOrOutOfFlowPositioned())
-        return false;
-
-    // We never margin collapse the initial containing block.
-    ASSERT(layoutBox.parent());
-    auto& parent = *layoutBox.parent();
-    // Is this the last inlflow child?
-    if (parent.lastInFlowChild() != &layoutBox)
-        return false;
-
-    if (parent.establishesBlockFormattingContext())
-        return false;
-
-    // Margins of the root element's box do not collapse.
-    if (parent.isInitialContainingBlock())
-        return false;
-
-    if (!parent.style().borderTop().nonZero())
-        return false;
-
-    if (!parent.style().paddingTop().isZero())
-        return false;
-
-    if (!parent.style().height().isAuto())
-        return false;
-
-    return true;
-}
-
 static LayoutUnit collapsedMarginTopFromFirstChild(const Box& layoutBox)
 {
     // Check if the first child collapses its margin top.
@@ -171,7 +135,7 @@
         return 0;
 
     auto& lastInFlowChild = *downcast<Container>(layoutBox).lastInFlowChild();
-    if (!isMarginBottomCollapsedWithParent(lastInFlowChild))
+    if (!BlockMarginCollapse::isMarginBottomCollapsedWithParent(lastInFlowChild))
         return 0;
 
     // Collect collapsed margin bottom recursively.
@@ -249,6 +213,47 @@
     return nonCollapsedMarginBottom(layoutBox);
 }
 
+bool BlockMarginCollapse::isMarginBottomCollapsedWithParent(const Box& layoutBox)
+{
+    // last inflow box to parent.
+    // https://www.w3.org/TR/CSS21/box.html#collapsing-margins
+    if (layoutBox.isAnonymous())
+        return false;
+
+    if (layoutBox.isFloatingOrOutOfFlowPositioned())
+        return false;
+
+    // We never margin collapse the initial containing block.
+    ASSERT(layoutBox.parent());
+    auto& parent = *layoutBox.parent();
+    // Is this the last inlflow child?
+    if (parent.lastInFlowChild() != &layoutBox)
+        return false;
+
+    if (parent.establishesBlockFormattingContext())
+        return false;
+
+    // Margins of the root element's box do not collapse.
+    if (parent.isInitialContainingBlock())
+        return false;
+
+    if (!parent.style().borderTop().nonZero())
+        return false;
+
+    if (!parent.style().paddingTop().isZero())
+        return false;
+
+    if (!parent.style().height().isAuto())
+        return false;
+
+    return true;
 }
+
+bool BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom(const Box&)
+{
+    return false;
 }
+
+}
+}
 #endif

Modified: trunk/Source/WebCore/layout/blockformatting/BlockMarginCollapse.h (231641 => 231642)


--- trunk/Source/WebCore/layout/blockformatting/BlockMarginCollapse.h	2018-05-10 16:16:11 UTC (rev 231641)
+++ trunk/Source/WebCore/layout/blockformatting/BlockMarginCollapse.h	2018-05-10 16:46:54 UTC (rev 231642)
@@ -42,6 +42,9 @@
 public:
     static LayoutUnit marginTop(const Box&);
     static LayoutUnit marginBottom(const Box&);
+
+    static bool isMarginBottomCollapsedWithParent(const Box&);
+    static bool isMarginTopCollapsedWithParentMarginBottom(const Box&);
 };
 
 }

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (231641 => 231642)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2018-05-10 16:16:11 UTC (rev 231641)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2018-05-10 16:46:54 UTC (rev 231642)
@@ -70,7 +70,7 @@
 {
 }
 
-void InlineFormattingContext::computeInFlowHeight(const Box&, Display::Box&) const
+void InlineFormattingContext::computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const
 {
 }
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (231641 => 231642)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2018-05-10 16:16:11 UTC (rev 231641)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2018-05-10 16:46:54 UTC (rev 231642)
@@ -49,7 +49,7 @@
 
 private:
     void computeInFlowWidth(const Box&, Display::Box&) const override;
-    void computeInFlowHeight(const Box&, Display::Box&) const override;
+    void computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const override;
 
 };
 

Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp (231641 => 231642)


--- trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp	2018-05-10 16:16:11 UTC (rev 231641)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp	2018-05-10 16:46:54 UTC (rev 231642)
@@ -179,6 +179,12 @@
     return !parent();
 }
 
+bool Box::isReplaced() const
+{
+    // HTMLAudioElement || HTMLCanvasElement || HTMLEmbedElement || HTMLIFrameElement || HTMLImageElement || HTMLInputElement || HTMLObjectElement || HTMLVideoElement
+    return false;
+}
+
 const Box* Box::nextInFlowSibling() const
 {
     if (auto* nextSibling = this->nextSibling()) {

Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.h (231641 => 231642)


--- trunk/Source/WebCore/layout/layouttree/LayoutBox.h	2018-05-10 16:16:11 UTC (rev 231641)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.h	2018-05-10 16:46:54 UTC (rev 231642)
@@ -72,6 +72,7 @@
     bool isInlineBlockBox() const;
     bool isBlockContainerBox() const;
     bool isInitialContainingBlock() const;
+    bool isReplaced() const;
 
     const Container* parent() const { return m_parent; }
     const Box* nextSibling() const { return m_nextSibling; }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to