Title: [237549] trunk
Revision
237549
Author
za...@apple.com
Date
2018-10-29 07:35:18 -0700 (Mon, 29 Oct 2018)

Log Message

[LFC][IFC] Add support for simple intruding floats.
https://bugs.webkit.org/show_bug.cgi?id=190998

Reviewed by Antti Koivisto.

Source/WebCore:

In order to be able to figure out whether a float is intruding on a line, we need to provide the line's final vertical position.
This vertical position must be in the same coordinate system as the float's position is. In case of intruding float,
it is the parent block formatting root's coordinate system (that's where the float lives.)

Test: fast/inline/simple-intruding-float1.html

* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::layoutFormattingContextRoot const):
(WebCore::Layout::BlockFormattingContext::computeEstimatedMarginTopForAncestors const):
(WebCore::Layout::BlockFormattingContext::precomputeVerticalPositionForFormattingRootIfNeeded const):
(WebCore::Layout::BlockFormattingContext::computeFloatingPosition const):
(WebCore::Layout::BlockFormattingContext::computePositionToAvoidFloats const):
(WebCore::Layout::BlockFormattingContext::computeVerticalPositionForFloatClear const):
* layout/blockformatting/BlockFormattingContext.h:
* layout/floats/FloatingState.cpp:
(WebCore::Layout::FloatingState::constraints const):

Tools:

* LayoutReloaded/misc/LFC-passing-tests.txt:

LayoutTests:

* fast/inline/simple-intruding-float1-expected.txt: Added.
* fast/inline/simple-intruding-float1.html: Added.
* platform/ios/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (237548 => 237549)


--- trunk/LayoutTests/ChangeLog	2018-10-29 14:19:09 UTC (rev 237548)
+++ trunk/LayoutTests/ChangeLog	2018-10-29 14:35:18 UTC (rev 237549)
@@ -1,5 +1,16 @@
 2018-10-29  Zalan Bujtas  <za...@apple.com>
 
+        [LFC][IFC] Add support for simple intruding floats.
+        https://bugs.webkit.org/show_bug.cgi?id=190998
+
+        Reviewed by Antti Koivisto.
+
+        * fast/inline/simple-intruding-float1-expected.txt: Added.
+        * fast/inline/simple-intruding-float1.html: Added.
+        * platform/ios/TestExpectations:
+
+2018-10-29  Zalan Bujtas  <za...@apple.com>
+
         [LFC][IFC] Inline layout produces separate runs when float is present.
         https://bugs.webkit.org/show_bug.cgi?id=190980
 

Added: trunk/LayoutTests/fast/inline/simple-intruding-float1-expected.txt (0 => 237549)


--- trunk/LayoutTests/fast/inline/simple-intruding-float1-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/inline/simple-intruding-float1-expected.txt	2018-10-29 14:35:18 UTC (rev 237549)
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderImage {IMG} at (0,0) size 20x100
+      RenderBlock {DIV} at (0,0) size 300x54
+        RenderText {#text} at (40,0) size 34x18
+          text run at (40,0) width 34: "thisis"
+        RenderImage {IMG} at (20,0) size 20x30
+        RenderText {#text} at (73,0) size 276x54
+          text run at (73,0) width 212: "one run long long long long long"
+          text run at (40,18) width 256: "long long long long long long long long"
+          text run at (20,36) width 89: "long long text"

Added: trunk/LayoutTests/fast/inline/simple-intruding-float1.html (0 => 237549)


--- trunk/LayoutTests/fast/inline/simple-intruding-float1.html	                        (rev 0)
+++ trunk/LayoutTests/fast/inline/simple-intruding-float1.html	2018-10-29 14:35:18 UTC (rev 237549)
@@ -0,0 +1 @@
+<img style="float: left;" src="" height="100" width="20"><div style="text-align: left; width: 300px;">thisis<img style="float: left;" src="" height="30" width="20">one run long long long long long long long long long long long long long long long text</div>

Modified: trunk/Source/WebCore/ChangeLog (237548 => 237549)


--- trunk/Source/WebCore/ChangeLog	2018-10-29 14:19:09 UTC (rev 237548)
+++ trunk/Source/WebCore/ChangeLog	2018-10-29 14:35:18 UTC (rev 237549)
@@ -1,5 +1,29 @@
 2018-10-29  Zalan Bujtas  <za...@apple.com>
 
+        [LFC][IFC] Add support for simple intruding floats.
+        https://bugs.webkit.org/show_bug.cgi?id=190998
+
+        Reviewed by Antti Koivisto.
+
+        In order to be able to figure out whether a float is intruding on a line, we need to provide the line's final vertical position.
+        This vertical position must be in the same coordinate system as the float's position is. In case of intruding float,
+        it is the parent block formatting root's coordinate system (that's where the float lives.)
+
+        Test: fast/inline/simple-intruding-float1.html
+
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::layoutFormattingContextRoot const):
+        (WebCore::Layout::BlockFormattingContext::computeEstimatedMarginTopForAncestors const):
+        (WebCore::Layout::BlockFormattingContext::precomputeVerticalPositionForFormattingRootIfNeeded const):
+        (WebCore::Layout::BlockFormattingContext::computeFloatingPosition const):
+        (WebCore::Layout::BlockFormattingContext::computePositionToAvoidFloats const):
+        (WebCore::Layout::BlockFormattingContext::computeVerticalPositionForFloatClear const):
+        * layout/blockformatting/BlockFormattingContext.h:
+        * layout/floats/FloatingState.cpp:
+        (WebCore::Layout::FloatingState::constraints const):
+
+2018-10-29  Zalan Bujtas  <za...@apple.com>
+
         [LFC][IFC] Inline layout produces separate runs when float is present.
         https://bugs.webkit.org/show_bug.cgi?id=190980
 

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (237548 => 237549)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2018-10-29 14:19:09 UTC (rev 237548)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2018-10-29 14:35:18 UTC (rev 237549)
@@ -132,6 +132,7 @@
     computeBorderAndPadding(layoutContext, layoutBox);
     computeWidthAndMargin(layoutContext, layoutBox);
 
+    precomputeVerticalPositionForFormattingRootIfNeeded(layoutContext, layoutBox);
     // Swich over to the new formatting context (the one that the root creates).
     auto formattingContext = layoutContext.formattingContext(layoutBox);
     auto& formattingState = layoutContext.createFormattingStateForFormattingRootIfNeeded(layoutBox);
@@ -171,7 +172,7 @@
 void BlockFormattingContext::computeEstimatedMarginTopForAncestors(const LayoutContext& layoutContext, const Box& layoutBox) const
 {
     // We only need to estimate margin top for float related layout (formatting context roots avoid floats).
-    ASSERT(layoutBox.isFloatingPositioned() || layoutBox.hasFloatClear() || layoutBox.establishesBlockFormattingContext());
+    ASSERT(layoutBox.isFloatingPositioned() || layoutBox.hasFloatClear() || layoutBox.establishesBlockFormattingContext() || layoutBox.establishesInlineFormattingContext());
 
     // In order to figure out whether a box should avoid a float, we need to know the final positions of both (ignore relative positioning for now).
     // In block formatting context the final position for a normal flow box includes
@@ -193,9 +194,34 @@
     }
 }
 
+void BlockFormattingContext::precomputeVerticalPositionForFormattingRootIfNeeded(const LayoutContext& layoutContext, const Box& layoutBox) const
+{
+    ASSERT(layoutBox.establishesFormattingContext());
+
+    auto avoidsFloats = (layoutBox.establishesBlockFormattingContext() && !layoutBox.establishesInlineFormattingContext()) || layoutBox.hasFloatClear();
+    if (layoutBox.isFloatingPositioned() || avoidsFloats)
+        computeEstimatedMarginTopForAncestors(layoutContext, layoutBox);
+
+    // If the inline formatting root is also the root for the floats (happens when the root box also establishes a block formatting context)
+    // the floats are in the coordinate system of this root. No need to find the final vertical position.
+    auto inlineContextInheritsFloats = layoutBox.establishesInlineFormattingContext() && !layoutBox.establishesBlockFormattingContext();
+    if (inlineContextInheritsFloats)
+        computeEstimatedMarginTop(layoutContext, layoutBox);
+}
+
+#ifndef NDEBUG
+static bool hasPrecomputedMarginTop(const LayoutContext& layoutContext, const Box& layoutBox)
+{
+    for (auto* ancestor = layoutBox.containingBlock(); ancestor && !ancestor->establishesBlockFormattingContext(); ancestor = ancestor->containingBlock())
+        ASSERT(displayBox.layoutContext.displayBoxForLayoutBox(*ancestor).estimatedMarginTop());
+}
+#endif
+
 void BlockFormattingContext::computeFloatingPosition(const LayoutContext& layoutContext, const FloatingContext& floatingContext, const Box& layoutBox) const
 {
     ASSERT(layoutBox.isFloatingPositioned());
+    ASSERT(hasPrecomputedMarginTop(layoutContext, layoutBox));
+
     auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
     // 8.3.1 Collapsing margins
     // In block formatting context margins between a floated box and any other box do not collapse.
@@ -204,7 +230,6 @@
         auto& previousDisplayBox = layoutContext.displayBoxForLayoutBox(*previousInFlowBox);
         displayBox.moveVertically(previousDisplayBox.nonCollapsedMarginBottom() - previousDisplayBox.marginBottom());
     }
-    computeEstimatedMarginTopForAncestors(layoutContext, layoutBox);
     displayBox.setTopLeft(floatingContext.positionForFloat(layoutBox));
 }
 
@@ -214,11 +239,11 @@
     ASSERT(layoutBox.establishesBlockFormattingContext());
     ASSERT(!layoutBox.isFloatingPositioned());
     ASSERT(!layoutBox.hasFloatClear());
+    ASSERT(hasPrecomputedMarginTop(layoutContext, layoutBox));
 
     if (floatingContext.floatingState().isEmpty())
         return;
 
-    computeEstimatedMarginTopForAncestors(layoutContext, layoutBox);
     if (auto adjustedPosition = floatingContext.positionForFloatAvoiding(layoutBox))
         layoutContext.displayBoxForLayoutBox(layoutBox).setTopLeft(*adjustedPosition);
 }
@@ -229,7 +254,11 @@
     if (floatingContext.floatingState().isEmpty())
         return;
 
-    computeEstimatedMarginTopForAncestors(layoutContext, layoutBox);
+    // For formatting roots, we already precomputed final position.
+    if (!layoutBox.establishesFormattingContext())
+        computeEstimatedMarginTopForAncestors(layoutContext, layoutBox);
+    ASSERT(hasPrecomputedMarginTop(layoutContext, layoutBox));
+
     if (auto verticalPositionWithClearance = floatingContext.verticalPositionWithClearance(layoutBox))
         layoutContext.displayBoxForLayoutBox(layoutBox).setTop(*verticalPositionWithClearance);
 }

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h (237548 => 237549)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2018-10-29 14:19:09 UTC (rev 237548)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2018-10-29 14:35:18 UTC (rev 237549)
@@ -61,9 +61,11 @@
     void computeVerticalPositionForFloatClear(const LayoutContext&, const FloatingContext&, const Box&) const;
 
     void computeInFlowPositionedPosition(const LayoutContext&, const Box&) const override;
+    void computeEstimatedMarginTopForAncestors(const LayoutContext&, const Box&) const;
     void computeEstimatedMarginTop(const LayoutContext&, const Box&) const;
-    void computeEstimatedMarginTopForAncestors(const LayoutContext&, const Box&) const;
 
+    void precomputeVerticalPositionForFormattingRootIfNeeded(const LayoutContext&, const Box&) const;
+
     InstrinsicWidthConstraints instrinsicWidthConstraints(LayoutContext&, const Box&) const override;
 
     // This class implements positioning and sizing for boxes participating in a block formatting context.

Modified: trunk/Source/WebCore/layout/floats/FloatingState.cpp (237548 => 237549)


--- trunk/Source/WebCore/layout/floats/FloatingState.cpp	2018-10-29 14:19:09 UTC (rev 237548)
+++ trunk/Source/WebCore/layout/floats/FloatingState.cpp	2018-10-29 14:35:18 UTC (rev 237549)
@@ -111,7 +111,7 @@
             continue;
 
         auto rect = floatItem.rectWithMargin();
-        if (!(rect.top() <= verticalPosition && verticalPosition < rect.bottom()))
+        if (!(rect.top() <= adjustedPosition.y && adjustedPosition.y < rect.bottom()))
             continue;
 
         if (floatItem.isLeftPositioned())

Modified: trunk/Tools/ChangeLog (237548 => 237549)


--- trunk/Tools/ChangeLog	2018-10-29 14:19:09 UTC (rev 237548)
+++ trunk/Tools/ChangeLog	2018-10-29 14:35:18 UTC (rev 237549)
@@ -1,5 +1,14 @@
 2018-10-29  Zalan Bujtas  <za...@apple.com>
 
+        [LFC][IFC] Add support for simple intruding floats.
+        https://bugs.webkit.org/show_bug.cgi?id=190998
+
+        Reviewed by Antti Koivisto.
+
+        * LayoutReloaded/misc/LFC-passing-tests.txt:
+
+2018-10-29  Zalan Bujtas  <za...@apple.com>
+
         [LFC][IFC] Inline layout produces separate runs when float is present.
         https://bugs.webkit.org/show_bug.cgi?id=190980
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to