- 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