Title: [267700] trunk
Revision
267700
Author
[email protected]
Date
2020-09-28 08:00:14 -0700 (Mon, 28 Sep 2020)

Log Message

[LFC][Floats] Add support for clear on float box
https://bugs.webkit.org/show_bug.cgi?id=217045

Reviewed by Antti Koivisto.

Source/WebCore:

When the float box also has to clear other floats, we need to adjust the initial
vertical position from where we start searching for available space.
(This patch also fixes a previous find&replace renaming and addresses a post-landing comment.)

Test: fast/layoutformattingcontext/float-with-clear-simple.html

* layout/floats/FloatingContext.cpp:
(WebCore::Layout::FloatingContext::positionForFloat const):
(WebCore::Layout::FloatingContext::positionForNonFloatingFloatAvoider const):
(WebCore::Layout::FloatingContext::absoluteCoordinates const):
(WebCore::Layout::FloatingContext::absoluteBoxGeometryCoordinates const): Deleted.
* layout/floats/FloatingContext.h:

LayoutTests:

* fast/layoutformattingcontext/float-with-clear-simple-expected.html: Added.
* fast/layoutformattingcontext/float-with-clear-simple.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (267699 => 267700)


--- trunk/LayoutTests/ChangeLog	2020-09-28 14:55:51 UTC (rev 267699)
+++ trunk/LayoutTests/ChangeLog	2020-09-28 15:00:14 UTC (rev 267700)
@@ -1,3 +1,13 @@
+2020-09-28  Zalan Bujtas  <[email protected]>
+
+        [LFC][Floats] Add support for clear on float box
+        https://bugs.webkit.org/show_bug.cgi?id=217045
+
+        Reviewed by Antti Koivisto.
+
+        * fast/layoutformattingcontext/float-with-clear-simple-expected.html: Added.
+        * fast/layoutformattingcontext/float-with-clear-simple.html: Added.
+
 2020-09-28  Angelos Oikonomopoulos  <[email protected]>
 
         Fix test failures inadventently introduced in r267644

Added: trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple-expected.html (0 => 267700)


--- trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple-expected.html	2020-09-28 15:00:14 UTC (rev 267700)
@@ -0,0 +1,22 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+.float {
+  width: 20px;
+  height: 20px;
+  background-color: blue;
+  position: relative;
+}
+</style>
+<div style="position: absolute; top: 8px; left: 8px; background-color: green; width: 40px; height: 240px"></div>
+<div class=float></div>
+<div class=float></div>
+<div class=float style="left: 20px;"></div>
+<div class=float style="left: 20px;"></div>
+<div class=float style="left: 20px;"></div>
+<div class=float></div>
+<div class=float></div>
+<div class=float style="left: 20px;"></div>
+<div class=float></div>
+<div class=float style="top: -20px; left: 20px;"></div>
+<div class=float></div>
+<div class=float style="top: -20px; left: 20px;"></div>

Added: trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple.html (0 => 267700)


--- trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple.html	                        (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple.html	2020-09-28 15:00:14 UTC (rev 267700)
@@ -0,0 +1,38 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+div {
+  overflow: hidden;
+  width: 40px;
+  height: 40px;
+  background-color: green;
+}
+.float {
+  background-color: blue;
+  width: 20px;
+  height: 20px;
+}
+</style>
+<div>
+  <div class=float style="float: left;"></div>
+  <div class=float style="float: left; clear: left"></div>
+</div>
+<div>
+  <div class=float style="float: right;"></div>
+  <div class=float style="float: right; clear: right"></div>
+</div>
+<div>
+  <div class=float style="float: right;"></div>
+  <div class=float style="float: left; clear: right"></div>
+</div>
+<div>
+  <div class=float style="float: left;"></div>
+  <div class=float style="float: right; clear: left"></div>
+</div>
+<div>
+  <div class=float style="float: left;"></div>
+  <div class=float style="float: right; clear: right"></div>
+</div>
+<div>
+  <div class=float style="float: right;"></div>
+  <div class=float style="float: left; clear: left"></div>
+</div>

Modified: trunk/Source/WebCore/ChangeLog (267699 => 267700)


--- trunk/Source/WebCore/ChangeLog	2020-09-28 14:55:51 UTC (rev 267699)
+++ trunk/Source/WebCore/ChangeLog	2020-09-28 15:00:14 UTC (rev 267700)
@@ -1,3 +1,23 @@
+2020-09-28  Zalan Bujtas  <[email protected]>
+
+        [LFC][Floats] Add support for clear on float box
+        https://bugs.webkit.org/show_bug.cgi?id=217045
+
+        Reviewed by Antti Koivisto.
+
+        When the float box also has to clear other floats, we need to adjust the initial
+        vertical position from where we start searching for available space.
+        (This patch also fixes a previous find&replace renaming and addresses a post-landing comment.) 
+
+        Test: fast/layoutformattingcontext/float-with-clear-simple.html
+
+        * layout/floats/FloatingContext.cpp:
+        (WebCore::Layout::FloatingContext::positionForFloat const):
+        (WebCore::Layout::FloatingContext::positionForNonFloatingFloatAvoider const):
+        (WebCore::Layout::FloatingContext::absoluteCoordinates const):
+        (WebCore::Layout::FloatingContext::absoluteBoxGeometryCoordinates const): Deleted.
+        * layout/floats/FloatingContext.h:
+
 2020-09-28  Aditya Keerthi  <[email protected]>
 
         Crash under DateTimeEditElement::blurFromField

Modified: trunk/Source/WebCore/layout/FormattingState.cpp (267699 => 267700)


--- trunk/Source/WebCore/layout/FormattingState.cpp	2020-09-28 14:55:51 UTC (rev 267699)
+++ trunk/Source/WebCore/layout/FormattingState.cpp	2020-09-28 15:00:14 UTC (rev 267700)
@@ -52,7 +52,7 @@
 {
     // Should never need to mutate a display box outside of the formatting context.
     ASSERT(&layoutState().establishedFormattingState(layoutBox.formattingContextRoot()) == this);
-    // Anonymous text wrappers do not need display boxes.
+    // Anonymous text wrappers do not need to compute box geometry. They initiate inline runs.
     ASSERT(!layoutBox.isInlineTextBox());
     return layoutState().ensureGeometryForBox(layoutBox);
 }

Modified: trunk/Source/WebCore/layout/floats/FloatingContext.cpp (267699 => 267700)


--- trunk/Source/WebCore/layout/floats/FloatingContext.cpp	2020-09-28 14:55:51 UTC (rev 267699)
+++ trunk/Source/WebCore/layout/floats/FloatingContext.cpp	2020-09-28 15:00:14 UTC (rev 267700)
@@ -227,15 +227,12 @@
 
     if (isEmpty()) {
         auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
-
         auto alignWithContainingBlock = [&]() -> Position {
             // If there is no floating to align with, push the box to the left/right edge of its containing block's content box.
             if (layoutBox.isLeftFloatingPositioned())
                 return { horizontalConstraints.logicalLeft + boxGeometry.marginStart() };
-
             return { horizontalConstraints.logicalRight() - boxGeometry.marginEnd() - boxGeometry.logicalWidth() };
         };
-
         // No float box on the context yet -> align it with the containing block's left/right edge.
         return { alignWithContainingBlock(), boxGeometry.logicalTop() };
     }
@@ -242,20 +239,42 @@
 
     // Find the top most position where the float box fits.
     ASSERT(!isEmpty());
-    auto previousFloatAbsoluteTop = floatingState().floats().last().rectWithMargin().top();
-    auto absoluteBoxGeometryCoordinates = this->absoluteBoxGeometryCoordinates(layoutBox);
-    auto absoluteTopLeft = absoluteBoxGeometryCoordinates.topLeft;
-    // Incoming float cannot be placed higher than existing floats (margin box of the last float).
-    // Take the static position (where the box would go if it wasn't floating) and adjust it with the last float.
+    auto absoluteCoordinates = this->absoluteCoordinates(layoutBox);
+    auto absoluteTopLeft = absoluteCoordinates.topLeft;
+    auto verticalPositionCandidate = absoluteTopLeft.y();
+
     auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
-    if (absoluteTopLeft.y() - boxGeometry.marginBefore() < previousFloatAbsoluteTop)
-        absoluteTopLeft.setY(previousFloatAbsoluteTop + boxGeometry.marginBefore());
+    if (layoutBox.hasFloatClear()) {
+        // The vertical position candidate needs to clear the existing floats in this context.
+        auto floatBottom = [&]() -> Optional<PositionInContextRoot> {
+            switch (layoutBox.style().clear()) {
+            case Clear::Left:
+                return floatingState().leftBottom(root());
+            case Clear::Right:
+                return floatingState().rightBottom(root());
+            case Clear::Both:
+                return floatingState().bottom(root());
+            default:
+                ASSERT_NOT_REACHED();
+            }
+            return { };
+        };
+        if (auto bottomWithClear = floatBottom())
+            verticalPositionCandidate = *bottomWithClear + boxGeometry.marginBefore();
+    } else {
+        // Incoming float cannot be placed higher than existing floats (margin box of the last float).
+        // Take the static position (where the box would go if it wasn't floating) and adjust it with the last float.
+        auto previousFloatAbsoluteTop = floatingState().floats().last().rectWithMargin().top();
+        if (verticalPositionCandidate - boxGeometry.marginBefore() < previousFloatAbsoluteTop)
+            verticalPositionCandidate = previousFloatAbsoluteTop + boxGeometry.marginBefore();
+    }
+    absoluteTopLeft.setY(verticalPositionCandidate);
     auto horizontalMargin = computedHorizontalMargin(layoutBox, horizontalConstraints.logicalWidth);
     auto margins = Edges { { *horizontalMargin.start, *horizontalMargin.end }, { boxGeometry.marginBefore(), boxGeometry.marginAfter() } };
-    auto floatBox = FloatAvoider { layoutBox, absoluteTopLeft, boxGeometry.logicalWidth(), margins, absoluteBoxGeometryCoordinates.containingBlockContentBox };
+    auto floatBox = FloatAvoider { layoutBox, absoluteTopLeft, boxGeometry.logicalWidth(), margins, absoluteCoordinates.containingBlockContentBox };
     findAvailablePosition(floatBox, m_floatingState.floats());
-    // From formatting root coordinate system back to containing block's.
-    auto containingBlockTopLeft = absoluteBoxGeometryCoordinates.containingBlockTopLeft;
+    // Convert box coordinates from formatting root back to containing block.
+    auto containingBlockTopLeft = absoluteCoordinates.containingBlockTopLeft;
     return { floatBox.left() + margins.horizontal.left - containingBlockTopLeft.x(), floatBox.top() + margins.vertical.top - containingBlockTopLeft.y() };
 }
 
@@ -269,13 +288,13 @@
     if (isEmpty())
         return formattingContext().geometryForBox(layoutBox).logicalTopLeft();
 
-    auto absoluteBoxGeometryCoordinates = this->absoluteBoxGeometryCoordinates(layoutBox);
+    auto absoluteCoordinates = this->absoluteCoordinates(layoutBox);
     auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
     auto horizontalMargin = computedHorizontalMargin(layoutBox, horizontalConstraints.logicalWidth);
     auto margins = Edges { { *horizontalMargin.start, *horizontalMargin.end }, { boxGeometry.marginBefore(), boxGeometry.marginAfter() } };
-    auto floatAvoider = FloatAvoider { layoutBox, absoluteBoxGeometryCoordinates.topLeft, boxGeometry.logicalWidth(), margins, absoluteBoxGeometryCoordinates.containingBlockContentBox };
+    auto floatAvoider = FloatAvoider { layoutBox, absoluteCoordinates.topLeft, boxGeometry.logicalWidth(), margins, absoluteCoordinates.containingBlockContentBox };
     findPositionForFormattingContextRoot(floatAvoider);
-    auto containingBlockTopLeft = absoluteBoxGeometryCoordinates.containingBlockTopLeft;
+    auto containingBlockTopLeft = absoluteCoordinates.containingBlockTopLeft;
     return { floatAvoider.left() - containingBlockTopLeft.x(), floatAvoider.top() - containingBlockTopLeft.y() };
 }
 
@@ -455,7 +474,7 @@
     }
 }
 
-FloatingContext::AbsoluteCoordinateValuesForFloatAvoider FloatingContext::absoluteBoxGeometryCoordinates(const Box& floatAvoider) const
+FloatingContext::AbsoluteCoordinateValuesForFloatAvoider FloatingContext::absoluteCoordinates(const Box& floatAvoider) const
 {
     auto& containingBlock = floatAvoider.containingBlock();
     auto& containingBlockGeometry = formattingContext().geometryForBox(containingBlock, FormattingContext::EscapeReason::FloatBoxNeedsToBeInAbsoluteCoordinates);

Modified: trunk/Source/WebCore/layout/floats/FloatingContext.h (267699 => 267700)


--- trunk/Source/WebCore/layout/floats/FloatingContext.h	2020-09-28 14:55:51 UTC (rev 267699)
+++ trunk/Source/WebCore/layout/floats/FloatingContext.h	2020-09-28 15:00:14 UTC (rev 267700)
@@ -74,7 +74,7 @@
     void findPositionForFormattingContextRoot(FloatAvoider&) const;
 
     struct AbsoluteCoordinateValuesForFloatAvoider;
-    AbsoluteCoordinateValuesForFloatAvoider absoluteBoxGeometryCoordinates(const Box&) const;
+    AbsoluteCoordinateValuesForFloatAvoider absoluteCoordinates(const Box&) const;
     LayoutPoint mapTopLeftToFloatingStateRoot(const Box&) const;
     Point mapPointFromFormattingContextRootToFloatingStateRoot(Point) const;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to