[LFC][Floating] Introduce FloatBox, a FloatAvoider subclass.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 29 Aug 2018 14:49:35 +0000 (14:49 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 29 Aug 2018 14:49:35 +0000 (14:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=189074

Reviewed by Antti Koivisto.

FloatBox is a float avoider and a float positioned box as well.
This is in preparation for the float avoidance feature where formatting context root boxes avoid existing floats.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/displaytree/DisplayBox.h:
* layout/floats/FloatAvoider.cpp:
(WebCore::Layout::FloatAvoider::FloatAvoider):
(WebCore::Layout::FloatAvoider::setHorizontalConstraints):
(WebCore::Layout::FloatAvoider::setVerticalConstraint):
(WebCore::Layout::FloatAvoider::horizontalPositionCandidate):
(WebCore::Layout::FloatAvoider::verticalPositionCandidate):
(WebCore::Layout::FloatAvoider::resetPosition):
(WebCore::Layout::FloatAvoider::rectInContainingBlock const):
(WebCore::Layout::FloatAvoider::initializePosition): Deleted.
(WebCore::Layout::FloatAvoider::isLeftAligned const): Deleted.
(WebCore::Layout::FloatAvoider::rect const): Deleted.
(WebCore::Layout::FloatAvoider::resetHorizontalConstraints): Deleted.
(WebCore::Layout::FloatAvoider::initialVerticalPosition const): Deleted.
* layout/floats/FloatAvoider.h:
(WebCore::Layout::FloatAvoider::rect const):
(WebCore::Layout::FloatAvoider::isLeftAligned const):
(WebCore::Layout::FloatAvoider::initialVerticalPosition const):
(WebCore::Layout::FloatAvoider::floatingState const):
(WebCore::Layout::FloatAvoider::layoutBox const):
(WebCore::Layout::FloatAvoider::displayBox const):
* layout/floats/FloatBox.cpp: Copied from Source/WebCore/layout/floats/FloatAvoider.h.
(WebCore::Layout::FloatBox::FloatBox):
(WebCore::Layout::FloatBox::horizontalPositionCandidate):
(WebCore::Layout::FloatBox::verticalPositionCandidate):
(WebCore::Layout::FloatBox::initialVerticalPosition const):
* layout/floats/FloatBox.h: Copied from Source/WebCore/layout/floats/FloatAvoider.h.
* layout/floats/FloatingContext.cpp:
(WebCore::Layout::FloatingContext::positionForFloat const):
(WebCore::Layout::FloatingContext::floatingPosition const):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235460 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/layout/displaytree/DisplayBox.h
Source/WebCore/layout/floats/FloatAvoider.cpp
Source/WebCore/layout/floats/FloatAvoider.h
Source/WebCore/layout/floats/FloatBox.cpp [new file with mode: 0644]
Source/WebCore/layout/floats/FloatBox.h [new file with mode: 0644]
Source/WebCore/layout/floats/FloatingContext.cpp

index 99e1cca..acd1656 100644 (file)
@@ -1,3 +1,46 @@
+2018-08-28  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][Floating] Introduce FloatBox, a FloatAvoider subclass.
+        https://bugs.webkit.org/show_bug.cgi?id=189074
+
+        Reviewed by Antti Koivisto.
+
+        FloatBox is a float avoider and a float positioned box as well.
+        This is in preparation for the float avoidance feature where formatting context root boxes avoid existing floats.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/displaytree/DisplayBox.h:
+        * layout/floats/FloatAvoider.cpp:
+        (WebCore::Layout::FloatAvoider::FloatAvoider):
+        (WebCore::Layout::FloatAvoider::setHorizontalConstraints):
+        (WebCore::Layout::FloatAvoider::setVerticalConstraint):
+        (WebCore::Layout::FloatAvoider::horizontalPositionCandidate):
+        (WebCore::Layout::FloatAvoider::verticalPositionCandidate):
+        (WebCore::Layout::FloatAvoider::resetPosition):
+        (WebCore::Layout::FloatAvoider::rectInContainingBlock const):
+        (WebCore::Layout::FloatAvoider::initializePosition): Deleted.
+        (WebCore::Layout::FloatAvoider::isLeftAligned const): Deleted.
+        (WebCore::Layout::FloatAvoider::rect const): Deleted.
+        (WebCore::Layout::FloatAvoider::resetHorizontalConstraints): Deleted.
+        (WebCore::Layout::FloatAvoider::initialVerticalPosition const): Deleted.
+        * layout/floats/FloatAvoider.h:
+        (WebCore::Layout::FloatAvoider::rect const):
+        (WebCore::Layout::FloatAvoider::isLeftAligned const):
+        (WebCore::Layout::FloatAvoider::initialVerticalPosition const):
+        (WebCore::Layout::FloatAvoider::floatingState const):
+        (WebCore::Layout::FloatAvoider::layoutBox const):
+        (WebCore::Layout::FloatAvoider::displayBox const):
+        * layout/floats/FloatBox.cpp: Copied from Source/WebCore/layout/floats/FloatAvoider.h.
+        (WebCore::Layout::FloatBox::FloatBox):
+        (WebCore::Layout::FloatBox::horizontalPositionCandidate):
+        (WebCore::Layout::FloatBox::verticalPositionCandidate):
+        (WebCore::Layout::FloatBox::initialVerticalPosition const):
+        * layout/floats/FloatBox.h: Copied from Source/WebCore/layout/floats/FloatAvoider.h.
+        * layout/floats/FloatingContext.cpp:
+        (WebCore::Layout::FloatingContext::positionForFloat const):
+        (WebCore::Layout::FloatingContext::floatingPosition const):
+
 2018-08-29  Ali Juma  <ajuma@chromium.org>
 
         [IntersectionObserver]  Implement intersection logic for the same-document implicit root case
index 80a74e4..aa8ccf7 100644 (file)
@@ -1230,6 +1230,7 @@ layout/blockformatting/BlockMarginCollapse.cpp
 layout/blockformatting/BlockInvalidation.cpp
 layout/displaytree/DisplayBox.cpp
 layout/floats/FloatAvoider.cpp
+layout/floats/FloatBox.cpp
 layout/floats/FloatingContext.cpp
 layout/floats/FloatingState.cpp
 layout/inlineformatting/InlineFormattingContext.cpp
index b6df748..8c0323c 100644 (file)
                6ED8C37A183BFF8C009E53BD /* BoxShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 6ED8C378183BFF8C009E53BD /* BoxShape.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6EE8A77310F803F3005A4A24 /* JSWebGLContextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EE8A77110F803F3005A4A24 /* JSWebGLContextAttributes.h */; };
                6F222B761AB52D8A0094651A /* WebGLVertexArrayObjectBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6F222B751AB52D8A0094651A /* WebGLVertexArrayObjectBase.cpp */; };
+               6F3E1F622136142000A65A08 /* FloatBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F3E1F612136141700A65A08 /* FloatBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6F7CA3C6208C2957002F29AB /* LayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F7CA3C4208C2956002F29AB /* LayoutContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6F7CA3CA208C2B2E002F29AB /* InlineFormattingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F7CA3C8208C2B2E002F29AB /* InlineFormattingContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6F995A151A70756200A735F4 /* WebGLSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6F995A131A70756200A735F4 /* WebGLSync.cpp */; };
                6F0830DF20B46951008A945B /* BlockFormattingContextGeometry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BlockFormattingContextGeometry.cpp; sourceTree = "<group>"; };
                6F222B741AB52D640094651A /* WebGLVertexArrayObjectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGLVertexArrayObjectBase.h; sourceTree = "<group>"; };
                6F222B751AB52D8A0094651A /* WebGLVertexArrayObjectBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebGLVertexArrayObjectBase.cpp; sourceTree = "<group>"; };
+               6F3E1F5F2136141700A65A08 /* FloatBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FloatBox.cpp; sourceTree = "<group>"; };
+               6F3E1F612136141700A65A08 /* FloatBox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FloatBox.h; sourceTree = "<group>"; };
                6F73918C2106CEDD006AF262 /* LayoutUnits.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutUnits.h; sourceTree = "<group>"; };
                6F7CA3C4208C2956002F29AB /* LayoutContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutContext.h; sourceTree = "<group>"; };
                6F7CA3C5208C2956002F29AB /* LayoutContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutContext.cpp; sourceTree = "<group>"; };
                        children = (
                                6FFDC43E212EFF1600A9CA91 /* FloatAvoider.cpp */,
                                6FFDC440212EFF1600A9CA91 /* FloatAvoider.h */,
+                               6F3E1F5F2136141700A65A08 /* FloatBox.cpp */,
+                               6F3E1F612136141700A65A08 /* FloatBox.h */,
                                115CFA85208B9066001E6991 /* FloatingContext.cpp */,
                                115CFA84208B9066001E6991 /* FloatingContext.h */,
                                115CFA81208B8EDA001E6991 /* FloatingState.cpp */,
                                372C00D9129619F8005C9575 /* FindOptions.h in Headers */,
                                A8CFF04F0A154F09000A4234 /* FixedTableLayout.h in Headers */,
                                6FFDC442212EFF1700A9CA91 /* FloatAvoider.h in Headers */,
+                               6F3E1F622136142000A65A08 /* FloatBox.h in Headers */,
                                BC073BAA0C399B1F000F5979 /* FloatConversion.h in Headers */,
                                115CFA86208B9066001E6991 /* FloatingContext.h in Headers */,
                                9A528E8417D7F52F00AA9518 /* FloatingObjects.h in Headers */,
index c945b44..e58f486 100644 (file)
@@ -36,8 +36,9 @@ namespace WebCore {
 class RenderStyle;
 
 namespace Layout {
-class FloatAvoider;
 class BlockFormattingContext;
+class FloatAvoider;
+class FloatBox;
 class FormattingContext;
 class FloatingContext;
 class LayoutContext;
@@ -48,8 +49,9 @@ namespace Display {
 class Box {
     WTF_MAKE_ISO_ALLOCATED(Box);
 public:
-    friend class Layout::FloatAvoider;
     friend class Layout::BlockFormattingContext;
+    friend class Layout::FloatAvoider;
+    friend class Layout::FloatBox;
     friend class Layout::FormattingContext;
     friend class Layout::FloatingContext;
     friend class Layout::LayoutContext;
index b284199..3f79df7 100644 (file)
@@ -43,68 +43,54 @@ FloatAvoider::FloatAvoider(const Box& layoutBox, const FloatingState& floatingSt
     , m_floatingState(floatingState)
     , m_absoluteDisplayBox(FormattingContext::mapBoxToAncestor(layoutContext, layoutBox, downcast<Container>(floatingState.root())))
     , m_containingBlockAbsoluteDisplayBox(FormattingContext::mapBoxToAncestor(layoutContext, *layoutBox.containingBlock(), downcast<Container>(floatingState.root())))
+    , m_initialVerticalPosition(m_absoluteDisplayBox.top())
 {
-    initializePosition();
 }
 
-void FloatAvoider::initializePosition()
+void FloatAvoider::setHorizontalConstraints(HorizontalConstraints horizontalConstraints)
 {
-    m_absoluteDisplayBox.setTopLeft({ initialHorizontalPosition(), initialVerticalPosition() });
-}
+    if ((isLeftAligned() && !horizontalConstraints.left) || (!isLeftAligned() && !horizontalConstraints.right)) {
+        // No constraints? Set horizontal position back to the inital value.
+        m_absoluteDisplayBox.setLeft(initialHorizontalPosition());
+        return;
+    }
 
-bool FloatAvoider::isLeftAligned() const
-{
-    return m_layoutBox->isLeftFloatingPositioned();
-}
+    auto constrainWithContainingBlock = [&](auto left) -> PositionInContextRoot {
+        // Horizontal position is constrained by the containing block's content box.
+        // Compute the horizontal position for the new floating by taking both the contining block and the current left/right floats into account.
+        auto containingBlockContentBoxLeft = m_containingBlockAbsoluteDisplayBox.left() + m_containingBlockAbsoluteDisplayBox.contentBoxLeft();
+        auto containingBlockContentBoxRight = containingBlockContentBoxLeft + m_containingBlockAbsoluteDisplayBox.contentBoxWidth();
+        // Align it with the containing block's left edge first.
+        left = std::max(containingBlockContentBoxLeft + m_absoluteDisplayBox.marginLeft(), left);
+        // Make sure it does not overflow the containing block on the right.
+        auto marginBoxSize = m_absoluteDisplayBox.marginBox().width();
+        left = std::min(left, containingBlockContentBoxRight - marginBoxSize + m_absoluteDisplayBox.marginLeft());
+
+        return left;
+    };
 
-Display::Box::Rect FloatAvoider::rect() const
-{
-    return m_absoluteDisplayBox.rectWithMargin();
+    auto positionCandidate = horizontalPositionCandidate(horizontalConstraints);
+    m_absoluteDisplayBox.setLeft(constrainWithContainingBlock(positionCandidate));
 }
 
 void FloatAvoider::setVerticalConstraint(PositionInContextRoot verticalConstraint)
 {
-    m_absoluteDisplayBox.setTop(verticalConstraint + m_absoluteDisplayBox.marginTop());
+    m_absoluteDisplayBox.setTop(verticalPositionCandidate(verticalConstraint));
 }
 
-void FloatAvoider::setHorizontalConstraints(HorizontalConstraints horizontalConstraints)
+PositionInContextRoot FloatAvoider::horizontalPositionCandidate(HorizontalConstraints horizontalConstraints)
 {
-    if ((isLeftAligned() && !horizontalConstraints.left) || (!isLeftAligned() && !horizontalConstraints.right)) {
-        resetHorizontalConstraints();
-        return;
-    }
-
-    auto positionCandidate = isLeftAligned() ? *horizontalConstraints.left : *horizontalConstraints.right - rect().width();
-    // Horizontal position is constrained by the containing block's content box.
-    // Compute the horizontal position for the new floating by taking both the contining block and the current left/right floats into account.
-    auto containingBlockContentBoxLeft = m_containingBlockAbsoluteDisplayBox.left() + m_containingBlockAbsoluteDisplayBox.contentBoxLeft();
-    auto containingBlockContentBoxRight = containingBlockContentBoxLeft + m_containingBlockAbsoluteDisplayBox.contentBoxWidth();
-
-    positionCandidate += m_absoluteDisplayBox.marginLeft();
-    // Align it with the containing block's left edge first.
-    positionCandidate = std::max(containingBlockContentBoxLeft + m_absoluteDisplayBox.marginLeft(), positionCandidate);
-    // Make sure it does not overflow the containing block on the right.
-    auto marginBoxSize = m_absoluteDisplayBox.marginBox().width();
-    positionCandidate = std::min(positionCandidate, containingBlockContentBoxRight - marginBoxSize + m_absoluteDisplayBox.marginLeft());
-
-    m_absoluteDisplayBox.setLeft(positionCandidate);
+    return isLeftAligned() ? *horizontalConstraints.left : *horizontalConstraints.right - rect().width();
 }
 
-void FloatAvoider::resetHorizontalConstraints()
+PositionInContextRoot FloatAvoider::verticalPositionCandidate(PositionInContextRoot verticalConstraint)
 {
-    m_absoluteDisplayBox.setLeft(initialHorizontalPosition());
+    return verticalConstraint;
 }
 
-PositionInContextRoot FloatAvoider::initialVerticalPosition() const
+void FloatAvoider::resetPosition()
 {
-    // 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 top = m_absoluteDisplayBox.rectWithMargin().top();
-    if (auto lastFloat = m_floatingState.last())
-        top = std::max(top, lastFloat->rectWithMargin().top());
-    top += m_absoluteDisplayBox.marginTop();
-
-    return top;
+    m_absoluteDisplayBox.setTopLeft({ initialHorizontalPosition(), initialVerticalPosition() });
 }
 
 PositionInContextRoot FloatAvoider::initialHorizontalPosition() const
@@ -122,7 +108,7 @@ PositionInContextRoot FloatAvoider::initialHorizontalPosition() const
 Display::Box::Rect FloatAvoider::rectInContainingBlock() const
 {
     // From formatting root coordinate system back to containing block's.
-    if (m_layoutBox->containingBlock() == &m_floatingState.root())
+    if (layoutBox().containingBlock() == &floatingState().root())
         return m_absoluteDisplayBox.rect();
 
     return {
index e9ca415..55562ea 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "DisplayBox.h"
+#include "LayoutBox.h"
 #include "LayoutUnit.h"
 #include <wtf/IsoMalloc.h>
 #include <wtf/WeakPtr.h>
@@ -36,7 +37,6 @@ namespace WebCore {
 
 namespace Layout {
 
-class Box;
 class FloatingState;
 class LayoutContext;
 
@@ -44,8 +44,9 @@ class FloatAvoider {
     WTF_MAKE_ISO_ALLOCATED(FloatAvoider);
 public:
     FloatAvoider(const Box&, const FloatingState&, const LayoutContext&);
+    virtual ~FloatAvoider() = default;
 
-    Display::Box::Rect rect() const;
+    virtual Display::Box::Rect rect() const { return m_absoluteDisplayBox.rect(); }
     Display::Box::Rect rectInContainingBlock() const;
 
     struct HorizontalConstraints {
@@ -55,19 +56,28 @@ public:
     void setHorizontalConstraints(HorizontalConstraints);
     void setVerticalConstraint(PositionInContextRoot);
 
-private:
-    bool isLeftAligned() const;
+    void resetPosition();
+
+protected:
+    virtual bool isLeftAligned() const { return layoutBox().style().isLeftToRightDirection(); }
+    virtual PositionInContextRoot initialHorizontalPosition() const;
+    virtual PositionInContextRoot initialVerticalPosition() const { return m_initialVerticalPosition; }
 
-    void initializePosition();
-    PositionInContextRoot initialHorizontalPosition() const;
-    PositionInContextRoot initialVerticalPosition() const;
     void resetHorizontalConstraints();
 
+    virtual PositionInContextRoot horizontalPositionCandidate(HorizontalConstraints);
+    virtual PositionInContextRoot verticalPositionCandidate(PositionInContextRoot);
+
+    const FloatingState& floatingState() const { return m_floatingState; }
+    const Box& layoutBox() const { return *m_layoutBox; }
+    const Display::Box& displayBox() const { return m_absoluteDisplayBox; }
+
+private:
     WeakPtr<Box> m_layoutBox;
     const FloatingState& m_floatingState;
-
     Display::Box m_absoluteDisplayBox;
     Display::Box m_containingBlockAbsoluteDisplayBox;
+    PositionInContextRoot m_initialVerticalPosition;
 };
 
 }
diff --git a/Source/WebCore/layout/floats/FloatBox.cpp b/Source/WebCore/layout/floats/FloatBox.cpp
new file mode 100644 (file)
index 0000000..290736f
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FloatBox.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(FloatBox);
+
+FloatBox::FloatBox(const Box& layoutBox, const FloatingState& floatingState, const LayoutContext& layoutContext)
+    : FloatAvoider(layoutBox, floatingState, layoutContext)
+{
+}
+
+PositionInContextRoot FloatBox::horizontalPositionCandidate(HorizontalConstraints horizontalConstraints)
+{
+    auto positionCandidate = isLeftAligned() ? *horizontalConstraints.left : *horizontalConstraints.right - rect().width();
+    positionCandidate += displayBox().marginLeft();
+
+    return positionCandidate;
+}
+
+PositionInContextRoot FloatBox::verticalPositionCandidate(PositionInContextRoot verticalConstraint)
+{
+    return verticalConstraint + displayBox().marginTop();
+}
+
+PositionInContextRoot FloatBox::initialVerticalPosition() const
+{
+    // 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 top = FloatAvoider::initialVerticalPosition() - displayBox().marginTop();
+    if (auto lastFloat = floatingState().last())
+        top = std::max(top, lastFloat->rectWithMargin().top());
+    top += displayBox().marginTop();
+
+    return top;
+}
+
+}
+}
+#endif
diff --git a/Source/WebCore/layout/floats/FloatBox.h b/Source/WebCore/layout/floats/FloatBox.h
new file mode 100644 (file)
index 0000000..ed7edae
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "FloatAvoider.h"
+#include <wtf/IsoMalloc.h>
+
+namespace WebCore {
+
+namespace Layout {
+
+class Box;
+class FloatingState;
+class LayoutContext;
+
+class FloatBox : public FloatAvoider {
+    WTF_MAKE_ISO_ALLOCATED(FloatBox);
+public:
+    FloatBox(const Box&, const FloatingState&, const LayoutContext&);
+
+    Display::Box::Rect rect() const final { return displayBox().rectWithMargin(); }
+
+private:
+    bool isLeftAligned() const final { return layoutBox().isLeftFloatingPositioned(); }
+
+    PositionInContextRoot horizontalPositionCandidate(HorizontalConstraints) final;
+    PositionInContextRoot verticalPositionCandidate(PositionInContextRoot) final;
+
+    PositionInContextRoot initialVerticalPosition() const final;
+};
+
+}
+}
+#endif
index 401929c..f15d68d 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "DisplayBox.h"
 #include "FloatAvoider.h"
+#include "FloatBox.h"
 #include "LayoutBox.h"
 #include "LayoutContainer.h"
 #include "LayoutContext.h"
@@ -137,9 +138,9 @@ PointInContainingBlock FloatingContext::positionForFloat(const Box& layoutBox) c
     }
 
     // Find the top most position where the float box fits.
-    FloatAvoider alignedBox = { layoutBox, m_floatingState, layoutContext() };
-    floatingPosition(alignedBox);
-    return alignedBox.rectInContainingBlock().topLeft();
+    FloatBox floatBox = { layoutBox, m_floatingState, layoutContext() };
+    floatingPosition(floatBox);
+    return floatBox.rectInContainingBlock().topLeft();
 }
 
 std::optional<PositionInContainingBlock> FloatingContext::verticalPositionWithClearance(const Box& layoutBox) const
@@ -215,6 +216,9 @@ std::optional<PositionInContainingBlock> FloatingContext::verticalPositionWithCl
 
 void FloatingContext::floatingPosition(FloatAvoider& floatAvoider) const
 {
+    // Ensure the float avoider starts with no constraints.
+    floatAvoider.resetPosition();
+
     std::optional<PositionInContextRoot> bottomMost;
     auto end = Layout::end(m_floatingState);
     for (auto iterator = begin(m_floatingState, floatAvoider.rect().top()); iterator != end; ++iterator) {