Title: [235178] trunk/Source/WebCore
Revision
235178
Author
za...@apple.com
Date
2018-08-22 10:10:34 -0700 (Wed, 22 Aug 2018)

Log Message

[LFC][Floating] Move files to a dedicated directory.
https://bugs.webkit.org/show_bug.cgi?id=188846

Reviewed by Simon Fraser.

layout/Float* -> layout/floats

* WebCore.xcodeproj/project.pbxproj:
* layout/floatformatting/FloatingContext.cpp: Renamed from Source/WebCore/layout/FloatingContext.cpp.
(WebCore::Layout::FloatingPair::isEmpty const):
(WebCore::Layout::FloatingPair::verticalPosition const):
(WebCore::Layout::Iterator::operator* const):
(WebCore::Layout::begin):
(WebCore::Layout::end):
(WebCore::Layout::FloatingContext::FloatingContext):
(WebCore::Layout::FloatingContext::positionForFloat const):
(WebCore::Layout::FloatingContext::verticalPositionWithClearance const):
(WebCore::Layout::FloatingContext::floatingPosition const):
(WebCore::Layout::FloatingContext::initialVerticalPosition const):
(WebCore::Layout::FloatingContext::alignWithContainingBlock const):
(WebCore::Layout::FloatingContext::alignWithFloatings const):
(WebCore::Layout::FloatingContext::toContainingBlock const):
(WebCore::Layout::FloatingPair::FloatingPair):
(WebCore::Layout::FloatingPair::left const):
(WebCore::Layout::FloatingPair::right const):
(WebCore::Layout::FloatingPair::intersects const):
(WebCore::Layout::FloatingPair::operator == const):
(WebCore::Layout::FloatingPair::bottom const):
(WebCore::Layout::Iterator::Iterator):
(WebCore::Layout::previousFloatingIndex):
(WebCore::Layout::Iterator::operator++):
(WebCore::Layout::Iterator::set):
(WebCore::Layout::Iterator::operator== const):
(WebCore::Layout::Iterator::operator!= const):
* layout/floatformatting/FloatingContext.h: Renamed from Source/WebCore/layout/FloatingContext.h.
(WebCore::Layout::FloatingContext::floatingState const):
(WebCore::Layout::FloatingContext::layoutContext const):
* layout/floatformatting/FloatingState.cpp: Renamed from Source/WebCore/layout/FloatingState.cpp.
(WebCore::Layout::FloatingState::FloatItem::FloatItem):
(WebCore::Layout::FloatingState::FloatingState):
(WebCore::Layout::belongsToThisFloatingContext):
(WebCore::Layout::FloatingState::remove):
(WebCore::Layout::FloatingState::append):
(WebCore::Layout::FloatingState::bottom const):
* layout/floatformatting/FloatingState.h: Renamed from Source/WebCore/layout/FloatingState.h.
(WebCore::Layout::FloatingState::create):
(WebCore::Layout::FloatingState::isEmpty const):
(WebCore::Layout::FloatingState::FloatItem::layoutBox const):
(WebCore::Layout::FloatingState::FloatItem::containingBlock const):
(WebCore::Layout::FloatingState::FloatItem::displayBox const):
(WebCore::Layout::FloatingState::FloatItem::containingBlockDisplayBox const):
(WebCore::Layout::FloatingState::floats const):
(WebCore::Layout::FloatingState::last const):
(WebCore::Layout::FloatingState::layoutContext const):
(WebCore::Layout::FloatingState::root const):
(WebCore::Layout::FloatingState::leftBottom const):
(WebCore::Layout::FloatingState::rightBottom const):
(WebCore::Layout::FloatingState::bottom const):

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (235177 => 235178)


--- trunk/Source/WebCore/ChangeLog	2018-08-22 16:55:19 UTC (rev 235177)
+++ trunk/Source/WebCore/ChangeLog	2018-08-22 17:10:34 UTC (rev 235178)
@@ -1,3 +1,64 @@
+2018-08-22  Zalan Bujtas  <za...@apple.com>
+
+        [LFC][Floating] Move files to a dedicated directory.
+        https://bugs.webkit.org/show_bug.cgi?id=188846
+
+        Reviewed by Simon Fraser.
+
+        layout/Float* -> layout/floats
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/floatformatting/FloatingContext.cpp: Renamed from Source/WebCore/layout/FloatingContext.cpp.
+        (WebCore::Layout::FloatingPair::isEmpty const):
+        (WebCore::Layout::FloatingPair::verticalPosition const):
+        (WebCore::Layout::Iterator::operator* const):
+        (WebCore::Layout::begin):
+        (WebCore::Layout::end):
+        (WebCore::Layout::FloatingContext::FloatingContext):
+        (WebCore::Layout::FloatingContext::positionForFloat const):
+        (WebCore::Layout::FloatingContext::verticalPositionWithClearance const):
+        (WebCore::Layout::FloatingContext::floatingPosition const):
+        (WebCore::Layout::FloatingContext::initialVerticalPosition const):
+        (WebCore::Layout::FloatingContext::alignWithContainingBlock const):
+        (WebCore::Layout::FloatingContext::alignWithFloatings const):
+        (WebCore::Layout::FloatingContext::toContainingBlock const):
+        (WebCore::Layout::FloatingPair::FloatingPair):
+        (WebCore::Layout::FloatingPair::left const):
+        (WebCore::Layout::FloatingPair::right const):
+        (WebCore::Layout::FloatingPair::intersects const):
+        (WebCore::Layout::FloatingPair::operator == const):
+        (WebCore::Layout::FloatingPair::bottom const):
+        (WebCore::Layout::Iterator::Iterator):
+        (WebCore::Layout::previousFloatingIndex):
+        (WebCore::Layout::Iterator::operator++):
+        (WebCore::Layout::Iterator::set):
+        (WebCore::Layout::Iterator::operator== const):
+        (WebCore::Layout::Iterator::operator!= const):
+        * layout/floatformatting/FloatingContext.h: Renamed from Source/WebCore/layout/FloatingContext.h.
+        (WebCore::Layout::FloatingContext::floatingState const):
+        (WebCore::Layout::FloatingContext::layoutContext const):
+        * layout/floatformatting/FloatingState.cpp: Renamed from Source/WebCore/layout/FloatingState.cpp.
+        (WebCore::Layout::FloatingState::FloatItem::FloatItem):
+        (WebCore::Layout::FloatingState::FloatingState):
+        (WebCore::Layout::belongsToThisFloatingContext):
+        (WebCore::Layout::FloatingState::remove):
+        (WebCore::Layout::FloatingState::append):
+        (WebCore::Layout::FloatingState::bottom const):
+        * layout/floatformatting/FloatingState.h: Renamed from Source/WebCore/layout/FloatingState.h.
+        (WebCore::Layout::FloatingState::create):
+        (WebCore::Layout::FloatingState::isEmpty const):
+        (WebCore::Layout::FloatingState::FloatItem::layoutBox const):
+        (WebCore::Layout::FloatingState::FloatItem::containingBlock const):
+        (WebCore::Layout::FloatingState::FloatItem::displayBox const):
+        (WebCore::Layout::FloatingState::FloatItem::containingBlockDisplayBox const):
+        (WebCore::Layout::FloatingState::floats const):
+        (WebCore::Layout::FloatingState::last const):
+        (WebCore::Layout::FloatingState::layoutContext const):
+        (WebCore::Layout::FloatingState::root const):
+        (WebCore::Layout::FloatingState::leftBottom const):
+        (WebCore::Layout::FloatingState::rightBottom const):
+        (WebCore::Layout::FloatingState::bottom const):
+
 2018-08-22  Rob Buis  <rb...@igalia.com>
 
         Fetch: Stop checking Request.integrity's value in no-cors mode

Modified: trunk/Source/WebCore/Sources.txt (235177 => 235178)


--- trunk/Source/WebCore/Sources.txt	2018-08-22 16:55:19 UTC (rev 235177)
+++ trunk/Source/WebCore/Sources.txt	2018-08-22 17:10:34 UTC (rev 235178)
@@ -1217,8 +1217,6 @@
 inspector/agents/worker/WorkerNetworkAgent.cpp
 inspector/agents/worker/WorkerRuntimeAgent.cpp
 
-layout/FloatingContext.cpp
-layout/FloatingState.cpp
 layout/FormattingContext.cpp
 layout/FormattingContextGeometry.cpp
 layout/FormattingState.cpp
@@ -1230,6 +1228,8 @@
 layout/blockformatting/BlockMarginCollapse.cpp
 layout/blockformatting/BlockInvalidation.cpp
 layout/displaytree/DisplayBox.cpp
+layout/floats/FloatingContext.cpp
+layout/floats/FloatingState.cpp
 layout/inlineformatting/InlineFormattingContext.cpp
 layout/inlineformatting/InlineFormattingState.cpp
 layout/inlineformatting/InlineInvalidation.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (235177 => 235178)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-08-22 16:55:19 UTC (rev 235177)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-08-22 17:10:34 UTC (rev 235178)
@@ -15665,12 +15665,9 @@
 			children = (
 				115CFA99208BC09A001E6991 /* blockformatting */,
 				1199FA58208E3C4C002358CC /* displaytree */,
+				6FCFC055212DACC2007695D2 /* floats */,
 				115CFA9A208BC140001E6991 /* inlineformatting */,
 				115CFA90208B9441001E6991 /* layouttree */,
-				115CFA85208B9066001E6991 /* FloatingContext.cpp */,
-				115CFA84208B9066001E6991 /* FloatingContext.h */,
-				115CFA81208B8EDA001E6991 /* FloatingState.cpp */,
-				115CFA80208B8EDA001E6991 /* FloatingState.h */,
 				115CFA69208AF7D0001E6991 /* FormattingContext.cpp */,
 				115CFA68208AF7D0001E6991 /* FormattingContext.h */,
 				6FBB860520B464B600DAD938 /* FormattingContextGeometry.cpp */,
@@ -19471,6 +19468,17 @@
 			path = simple;
 			sourceTree = "<group>";
 		};
+		6FCFC055212DACC2007695D2 /* floats */ = {
+			isa = PBXGroup;
+			children = (
+				115CFA85208B9066001E6991 /* FloatingContext.cpp */,
+				115CFA84208B9066001E6991 /* FloatingContext.h */,
+				115CFA81208B8EDA001E6991 /* FloatingState.cpp */,
+				115CFA80208B8EDA001E6991 /* FloatingState.h */,
+			);
+			path = floats;
+			sourceTree = "<group>";
+		};
 		6FE7DDDD20EC6E8B008B5B4E /* textlayout */ = {
 			isa = PBXGroup;
 			children = (

Deleted: trunk/Source/WebCore/layout/FloatingContext.cpp (235177 => 235178)


--- trunk/Source/WebCore/layout/FloatingContext.cpp	2018-08-22 16:55:19 UTC (rev 235177)
+++ trunk/Source/WebCore/layout/FloatingContext.cpp	2018-08-22 17:10:34 UTC (rev 235178)
@@ -1,516 +0,0 @@
-/*
- * 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 "FloatingContext.h"
-
-#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
-
-#include "DisplayBox.h"
-#include "LayoutBox.h"
-#include "LayoutContainer.h"
-#include "LayoutContext.h"
-#include <wtf/IsoMallocInlines.h>
-
-namespace WebCore {
-namespace Layout {
-
-WTF_MAKE_ISO_ALLOCATED_IMPL(FloatingContext);
-
-// Finding the top/left position for a new floating(F)
-//  ____  ____  _____               _______
-// |    || L2 ||     | <-----1---->|       |
-// |    ||____||  L3 |             |   R1  |
-// | L1 |      |_____|             |       |
-// |____| <-------------2--------->|       |
-//                                 |       |
-//                                 |_______|
-//
-// 1. Compute the initial vertical position for (F) -> (1)
-// 2. Find the corresponding floating pair (L3-R1)
-// 3. Align (F) horizontally with (L3-R1) depending whether (F) is left/right positioned
-// 4. Intersect (F) with (L3-R1)
-// 5. If (F) does not fit, find the next floating pair (L1-R1)
-// 6. Repeat until either (F) fits/no more floats.
-// Note that all coordinates are in the coordinate system of the formatting root.
-// The formatting root here is always the one that establishes the floating context (see inherited floating context).
-// (It simply means that the float box's formatting root is not necessarily the same as the FormattingContext's root.)
-
-class Iterator;
-
-class FloatingPair {
-public:
-    bool isEmpty() const { return !m_leftIndex && !m_rightIndex; }
-    const Display::Box* left() const;
-    const Display::Box* right() const;
-    bool intersects(const Display::Box::Rect&) const;
-    LayoutUnit verticalPosition() const { return m_verticalPosition; }
-    LayoutUnit bottom() const;
-    bool operator==(const FloatingPair&) const;
-
-private:
-    friend class Iterator;
-    FloatingPair(const FloatingState::FloatList&);
-
-    const FloatingState::FloatList& m_floats;
-
-    std::optional<unsigned> m_leftIndex;
-    std::optional<unsigned> m_rightIndex;
-    LayoutUnit m_verticalPosition;
-};
-
-class Iterator {
-public:
-    Iterator(const FloatingState::FloatList&, std::optional<LayoutUnit> verticalPosition);
-
-    const FloatingPair& operator*() const { return m_current; }
-    Iterator& operator++();
-    bool operator==(const Iterator&) const;
-    bool operator!=(const Iterator&) const;
-
-private:
-    void set(LayoutUnit verticalPosition);
-
-    const FloatingState::FloatList& m_floats;
-    FloatingPair m_current;
-};
-
-static Iterator begin(const FloatingState& floatingState, LayoutUnit initialVerticalPosition)
-{
-    // Start with the inner-most floating pair for the initial vertical position.
-    return Iterator(floatingState.floats(), initialVerticalPosition);
-}
-
-static Iterator end(const FloatingState& floatingState)
-{
-    return Iterator(floatingState.floats(), std::nullopt);
-}
-
-FloatingContext::FloatingContext(FloatingState& floatingState)
-    : m_floatingState(floatingState)
-{
-}
-
-Position FloatingContext::positionForFloat(const Box& layoutBox) const
-{
-    ASSERT(layoutBox.isFloatingPositioned());
-    FloatingState::FloatItem floatItem = { layoutBox, m_floatingState };
-
-    Position floatPosition;
-    if (m_floatingState.isEmpty()) {
-        // No float box on the context yet -> align it with the containing block's left/right edge.
-        auto& displayBox = floatItem.displayBox();
-        floatPosition = { alignWithContainingBlock(floatItem) + displayBox.marginLeft(), displayBox.top() };
-    } else {
-        // Find the top most position where the float box fits.
-        floatPosition = floatingPosition(floatItem);
-    }
-
-    return toContainingBlock(floatItem, floatPosition);
-}
-
-std::optional<LayoutUnit> FloatingContext::verticalPositionWithClearance(const Box& layoutBox) const
-{
-    ASSERT(layoutBox.hasFloatClear());
-    ASSERT(layoutBox.isBlockLevelBox());
-
-    if (m_floatingState.isEmpty())
-        return { };
-
-    auto bottom = [&](std::optional<LayoutUnit> floatBottom) -> std::optional<LayoutUnit> {
-        // 'bottom' is in the formatting root's coordinate system.
-        if (!floatBottom)
-            return { };
-
-        // 9.5.2 Controlling flow next to floats: the 'clear' property
-        // Then the amount of clearance is set to the greater of:
-        //
-        // 1. The amount necessary to place the border edge of the block even with the bottom outer edge of the lowest float that is to be cleared.
-        // 2. The amount necessary to place the top border edge of the block at its hypothetical position.
-
-        auto& layoutContext = this->layoutContext();
-        auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
-        auto rootRelativeTop = FormattingContext::mapTopLeftToAncestor(layoutContext, layoutBox, downcast<Container>(m_floatingState.root())).y;
-        auto clearance = *floatBottom - rootRelativeTop;
-        if (clearance <= 0)
-            return { };
-
-        // Clearance inhibits margin collapsing. Let's reset the relevant adjoining margins.
-        if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
-            auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
-
-            // Since the previous inflow sibling has already been laid out, its margin is collapsed by now.
-            ASSERT(!previousInFlowDisplayBox.marginBottom());
-            auto collapsedMargin = displayBox.marginTop();
-
-            // Reset previous bottom and current top margins to non-collapsing.
-            previousInFlowDisplayBox.setVerticalMargin({ previousInFlowDisplayBox.marginTop(), previousInFlowDisplayBox.nonCollapsedMarginBottom() });
-            displayBox.setVerticalMargin({ displayBox.nonCollapsedMarginTop(), displayBox.marginBottom() });
-
-            auto nonCollapsedMargin = previousInFlowDisplayBox.marginBottom() + displayBox.marginTop();
-            auto marginOffset = nonCollapsedMargin - collapsedMargin;
-            // Move the box to the position where it would be with non-collapsed margins.
-            rootRelativeTop += marginOffset;
-
-            // Having negative clearance is also normal. It just means that the box with the non-collapsed margins is now lower than it needs to be.
-            clearance -= marginOffset;
-        }
-        // Now adjust the box's position with the clearance.
-        rootRelativeTop += clearance;
-        ASSERT(*floatBottom == rootRelativeTop);
-
-        // The return vertical position is in the containing block's coordinate system.
-        auto containingBlockRootRelativeTop = FormattingContext::mapTopLeftToAncestor(layoutContext, *layoutBox.containingBlock(), downcast<Container>(m_floatingState.root())).y;
-        return rootRelativeTop - containingBlockRootRelativeTop;
-    };
-
-    auto clear = layoutBox.style().clear();
-    auto& formattingContextRoot = layoutBox.formattingContextRoot();
-
-    if (clear == Clear::Left)
-        return bottom(m_floatingState.leftBottom(formattingContextRoot));
-
-    if (clear == Clear::Right)
-        return bottom(m_floatingState.rightBottom(formattingContextRoot));
-
-    if (clear == Clear::Both)
-        return bottom(m_floatingState.bottom(formattingContextRoot));
-
-    ASSERT_NOT_REACHED();
-    return { };
-}
-
-Position FloatingContext::floatingPosition(const FloatingState::FloatItem& floatItem) const
-{
-    auto initialVerticalPosition = this->initialVerticalPosition(floatItem);
-    auto& displayBox = floatItem.displayBox();
-    auto marginBoxSize = displayBox.marginBox().size();
-
-    auto end = Layout::end(m_floatingState);
-    auto top = initialVerticalPosition;
-    auto bottomMost = top;
-    for (auto iterator = begin(m_floatingState, initialVerticalPosition); iterator != end; ++iterator) {
-        ASSERT(!(*iterator).isEmpty());
-
-        auto floats = *iterator;
-        top = floats.verticalPosition();
-
-        // Move the box horizontally so that it aligns with the current floating pair.
-        auto left = alignWithFloatings(floats, floatItem);
-        // Check if the box fits at this vertical position.
-        if (!floats.intersects({ top, left, marginBoxSize.width(), marginBoxSize.height() }))
-            return { left + displayBox.marginLeft(), top + displayBox.marginTop() };
-
-        bottomMost = floats.bottom();
-        // Move to the next floating pair.
-    }
-
-    // Passed all the floats and still does not fit?
-    return { alignWithContainingBlock(floatItem) + displayBox.marginLeft(), bottomMost + displayBox.marginTop() };
-}
-
-LayoutUnit FloatingContext::initialVerticalPosition(const FloatingState::FloatItem& floatItem) const
-{
-    // Incoming floating cannot be placed higher than existing floats.
-    // Take the static position (where the box would go if it wasn't floating) and adjust it with the last floating.
-    auto marginBoxTop = floatItem.displayBox().rectWithMargin().top();
-
-    if (auto lastFloat = m_floatingState.last())
-        return std::max(marginBoxTop, lastFloat->displayBox().rectWithMargin().top());
-
-    return marginBoxTop;
-}
-
-LayoutUnit FloatingContext::alignWithContainingBlock(const FloatingState::FloatItem& floatItem) const
-{
-    // If there is no floating to align with, push the box to the left/right edge of its containing block's content box.
-    // (Either there's no floats at all or this box does not fit at any vertical positions where the floats are.)
-    auto& containingBlockDisplayBox = floatItem.containingBlockDisplayBox();
-    auto containingBlockContentBoxLeft = containingBlockDisplayBox.left() + containingBlockDisplayBox.contentBoxLeft();
-
-    if (floatItem.layoutBox().isLeftFloatingPositioned())
-        return containingBlockContentBoxLeft;
-
-    return containingBlockContentBoxLeft + containingBlockDisplayBox.contentBoxWidth() - floatItem.displayBox().marginBox().width();
-}
-
-LayoutUnit FloatingContext::alignWithFloatings(const FloatingPair& floatingPair, const FloatingState::FloatItem& floatItem) const
-{
-    // Compute the horizontal position for the new floating by taking both the contining block and the current left/right floats into account.
-    auto& containingBlockDisplayBox = floatItem.containingBlockDisplayBox();
-    auto containingBlockContentBoxLeft = containingBlockDisplayBox.left() + containingBlockDisplayBox.contentBoxLeft();
-    auto containingBlockContentBoxRight = containingBlockDisplayBox.left() + containingBlockDisplayBox.contentBoxRight();
-    auto marginBoxWidth = floatItem.displayBox().marginBox().width();
-
-    auto leftAlignedBoxLeft = containingBlockContentBoxLeft;
-    auto rightAlignedBoxLeft = containingBlockContentBoxRight - marginBoxWidth;
-
-    if (floatingPair.isEmpty()) {
-        ASSERT_NOT_REACHED();
-        return floatItem.layoutBox().isLeftFloatingPositioned() ? leftAlignedBoxLeft : rightAlignedBoxLeft;
-    }
-
-    if (floatItem.layoutBox().isLeftFloatingPositioned()) {
-        if (auto* leftDisplayBox = floatingPair.left()) {
-            auto leftFloatingBoxRight = leftDisplayBox->rectWithMargin().right();
-            return std::min(std::max(leftAlignedBoxLeft, leftFloatingBoxRight), rightAlignedBoxLeft);
-        }
-        
-        return leftAlignedBoxLeft;
-    }
-
-    ASSERT(floatItem.layoutBox().isRightFloatingPositioned());
-
-    if (auto* rightDisplayBox = floatingPair.right()) {
-        auto rightFloatingBoxLeft = rightDisplayBox->rectWithMargin().left();
-        return std::max(std::min(rightAlignedBoxLeft, rightFloatingBoxLeft - marginBoxWidth), leftAlignedBoxLeft);
-    }
-
-    return rightAlignedBoxLeft;
-}
-
-// FIXME: find a better place for this.
-Position FloatingContext::toContainingBlock(const FloatingState::FloatItem& floatItem, Position position) const
-{
-    // From formatting root coordinate system back to containing block's.
-    if (&floatItem.containingBlock() == &m_floatingState.root())
-        return position;
-
-    auto& containingBlockDisplayBox = floatItem.containingBlockDisplayBox();
-    return { position.x - containingBlockDisplayBox.left(), position.y - containingBlockDisplayBox.top() };
-}
-
-FloatingPair::FloatingPair(const FloatingState::FloatList& floats)
-    : m_floats(floats)
-{
-}
-
-const Display::Box* FloatingPair::left() const
-{
-    if (!m_leftIndex)
-        return nullptr;
-
-    ASSERT(m_floats[*m_leftIndex].layoutBox().isLeftFloatingPositioned());
-    return &m_floats[*m_leftIndex].displayBox();
-}
-
-const Display::Box* FloatingPair::right() const
-{
-    if (!m_rightIndex)
-        return nullptr;
-
-    ASSERT(m_floats[*m_rightIndex].layoutBox().isRightFloatingPositioned());
-    return &m_floats[*m_rightIndex].displayBox();
-}
-
-bool FloatingPair::intersects(const Display::Box::Rect& candidateRect) const
-{
-    auto intersects = [&](const Display::Box* floating, Float floatingType) {
-        if (!floating)
-            return false;
-
-        auto marginRect = floating->rectWithMargin();
-        // Before intersecting, check if the candidate position is too far to the left/right.
-        // The new float's containing block could push the candidate position beyond the current float horizontally.
-        if ((floatingType == Float::Left && candidateRect.left() < marginRect.right())
-            || (floatingType == Float::Right && candidateRect.right() > marginRect.left()))
-            return true;
-        return marginRect.intersects(candidateRect);
-    };
-
-    if (!m_leftIndex && !m_rightIndex) {
-        ASSERT_NOT_REACHED();
-        return false;
-    }
-
-    if (intersects(left(), Float::Left))
-        return true;
-
-    if (intersects(right(), Float::Right))
-        return true;
-
-    return false;
-}
-
-bool FloatingPair::operator ==(const FloatingPair& other) const
-{
-    return m_leftIndex == other.m_leftIndex && m_rightIndex == other.m_rightIndex;
-}
-
-LayoutUnit FloatingPair::bottom() const
-{
-    auto* left = this->left();
-    auto* right = this->right();
-    ASSERT(left || right);
-
-    auto leftBottom = left ? std::optional<LayoutUnit>(left->rectWithMargin().bottom()) : std::nullopt;
-    auto rightBottom = right ? std::optional<LayoutUnit>(right->rectWithMargin().bottom()) : std::nullopt;
-
-    if (leftBottom && rightBottom)
-        return std::max(*leftBottom, *rightBottom);
-
-    if (leftBottom)
-        return *leftBottom;
-
-    return *rightBottom;
-}
-
-Iterator::Iterator(const FloatingState::FloatList& floats, std::optional<LayoutUnit> verticalPosition)
-    : m_floats(floats)
-    , m_current(floats)
-{
-    if (verticalPosition)
-        set(*verticalPosition);
-}
-
-inline static std::optional<unsigned> previousFloatingIndex(Float floatingType, const FloatingState::FloatList& floats, unsigned currentIndex)
-{
-    RELEASE_ASSERT(currentIndex <= floats.size());
-
-    while (currentIndex) {
-        auto& floating = floats[--currentIndex].layoutBox();
-        if ((floatingType == Float::Left && floating.isLeftFloatingPositioned()) || (floatingType == Float::Right && floating.isRightFloatingPositioned()))
-            return currentIndex;
-    }
-
-    return { };
-}
-
-Iterator& Iterator::operator++()
-{
-    if (m_current.isEmpty()) {
-        ASSERT_NOT_REACHED();
-        return *this;
-    }
-
-    auto findPreviousFloatingWithLowerBottom = [&](Float floatingType, unsigned currentIndex) -> std::optional<unsigned> {
-
-        RELEASE_ASSERT(currentIndex < m_floats.size());
-
-        // Last floating? There's certainly no previous floating at this point.
-        if (!currentIndex)
-            return { };
-
-        auto currentBottom = m_floats[currentIndex].displayBox().rectWithMargin().bottom();
-
-        std::optional<unsigned> index = currentIndex;
-        while (true) {
-            index = previousFloatingIndex(floatingType, m_floats, *index);
-            if (!index)
-                return { };
-
-            if (m_floats[*index].displayBox().rectWithMargin().bottom() > currentBottom)
-                return index;
-        }
-
-        ASSERT_NOT_REACHED();
-        return { };
-    };
-
-    // 1. Take the current floating from left and right and check which one's bottom edge is positioned higher (they could be on the same vertical position too).
-    // The current floats from left and right are considered the inner-most pair for the current vertical position.
-    // 2. Move away from inner-most pair by picking one of the previous floats in the list(#1)
-    // Ensure that the new floating's bottom edge is positioned lower than the current one -which essentially means skipping in-between floats that are positioned higher).
-    // 3. Reset the vertical position and align it with the new left-right pair. These floats are now the inner-most boxes for the current vertical position.
-    // As the result we have more horizontal space on the current vertical position.
-    auto leftBottom = m_current.left() ? std::optional<LayoutUnit>(m_current.left()->bottom()) : std::nullopt;
-    auto rightBottom = m_current.right() ? std::optional<LayoutUnit>(m_current.right()->bottom()) : std::nullopt;
-
-    auto updateLeft = (leftBottom == rightBottom) || (!rightBottom || (leftBottom && leftBottom < rightBottom)); 
-    auto updateRight = (leftBottom == rightBottom) || (!leftBottom || (rightBottom && leftBottom > rightBottom)); 
-
-    if (updateLeft) {
-        ASSERT(m_current.m_leftIndex);
-        m_current.m_verticalPosition = *leftBottom;
-        m_current.m_leftIndex = findPreviousFloatingWithLowerBottom(Float::Left, *m_current.m_leftIndex);
-    }
-    
-    if (updateRight) {
-        ASSERT(m_current.m_rightIndex);
-        m_current.m_verticalPosition = *rightBottom;
-        m_current.m_rightIndex = findPreviousFloatingWithLowerBottom(Float::Right, *m_current.m_rightIndex);
-    }
-
-    return *this;
-}
-
-void Iterator::set(LayoutUnit verticalPosition)
-{
-    // Move the iterator to the initial vertical position by starting at the inner-most floating pair (last floats on left/right).
-    // 1. Check if the inner-most pair covers the vertical position.
-    // 2. Move outwards from the inner-most pair until the vertical postion intersects.
-    // (Note that verticalPosition has already been adjusted with the top of the last float.)
-
-    m_current.m_verticalPosition = verticalPosition;
-    // No floats at all?
-    if (m_floats.isEmpty()) {
-        ASSERT_NOT_REACHED();
-
-        m_current.m_leftIndex = { };
-        m_current.m_rightIndex = { };
-        return;
-    }
-
-    auto findFloatingBelow = [&](Float floatingType) -> std::optional<unsigned> {
-
-        ASSERT(!m_floats.isEmpty());
-
-        auto index = floatingType == Float::Left ? m_current.m_leftIndex : m_current.m_rightIndex;
-        // Start from the end if we don't have current yet.
-        index = index.value_or(m_floats.size());
-        while (true) {
-            index = previousFloatingIndex(floatingType, m_floats, *index);
-            if (!index)
-                return { };
-
-            auto bottom = m_floats[*index].displayBox().rectWithMargin().bottom();
-            // Is this floating intrusive on this position?
-            if (bottom > verticalPosition)
-                return index;
-        }
-
-        return { };
-    };
-
-    m_current.m_leftIndex = findFloatingBelow(Float::Left);
-    m_current.m_rightIndex = findFloatingBelow(Float::Right);
-
-    ASSERT(!m_current.m_leftIndex || (*m_current.m_leftIndex < m_floats.size() && m_floats[*m_current.m_leftIndex].layoutBox().isLeftFloatingPositioned()));
-    ASSERT(!m_current.m_rightIndex || (*m_current.m_rightIndex < m_floats.size() && m_floats[*m_current.m_rightIndex].layoutBox().isRightFloatingPositioned()));
-}
-
-bool Iterator::operator==(const Iterator& other) const
-{
-    return m_current == other.m_current;
-}
-
-bool Iterator::operator!=(const Iterator& other) const
-{
-    return !(*this == other);
-}
-
-}
-}
-#endif

Deleted: trunk/Source/WebCore/layout/FloatingContext.h (235177 => 235178)


--- trunk/Source/WebCore/layout/FloatingContext.h	2018-08-22 16:55:19 UTC (rev 235177)
+++ trunk/Source/WebCore/layout/FloatingContext.h	2018-08-22 17:10:34 UTC (rev 235178)
@@ -1,70 +0,0 @@
-/*
- * 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 "FloatingState.h"
-#include "LayoutUnits.h"
-#include <wtf/IsoMalloc.h>
-
-namespace WebCore {
-
-namespace Layout {
-
-class Box;
-class Container;
-class FloatingPair;
-class LayoutContext;
-
-// FloatingContext is responsible for adjusting the position of a box in the current formatting context
-// by taking the floating boxes into account.
-class FloatingContext {
-    WTF_MAKE_ISO_ALLOCATED(FloatingContext);
-public:
-    FloatingContext(FloatingState&);
-
-    FloatingState& floatingState() const { return m_floatingState; }
-
-    Position positionForFloat(const Box&) const;
-    std::optional<LayoutUnit> verticalPositionWithClearance(const Box&) const;
-
-private:
-    LayoutContext& layoutContext() const { return m_floatingState.layoutContext(); }
-
-    Position floatingPosition(const FloatingState::FloatItem&) const;
-
-    LayoutUnit initialVerticalPosition(const FloatingState::FloatItem&) const;
-    LayoutUnit alignWithContainingBlock(const FloatingState::FloatItem&) const;
-    LayoutUnit alignWithFloatings(const FloatingPair&, const FloatingState::FloatItem&) const;
-    Position toContainingBlock(const FloatingState::FloatItem&, Position) const;
-
-    FloatingState& m_floatingState;
-};
-
-}
-}
-#endif

Deleted: trunk/Source/WebCore/layout/FloatingState.cpp (235177 => 235178)


--- trunk/Source/WebCore/layout/FloatingState.cpp	2018-08-22 16:55:19 UTC (rev 235177)
+++ trunk/Source/WebCore/layout/FloatingState.cpp	2018-08-22 17:10:34 UTC (rev 235178)
@@ -1,122 +0,0 @@
-/*
- * 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 "FloatingState.h"
-
-#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
-
-#include "FormattingContext.h"
-#include "LayoutBox.h"
-#include "LayoutContext.h"
-#include <wtf/IsoMallocInlines.h>
-
-namespace WebCore {
-namespace Layout {
-
-WTF_MAKE_ISO_ALLOCATED_IMPL(FloatingState);
-
-FloatingState::FloatItem::FloatItem(const Box& layoutBox, const FloatingState& floatingState)
-    : m_layoutBox(makeWeakPtr(const_cast<Box&>(layoutBox)))
-    , m_containingBlock(makeWeakPtr(const_cast<Container&>(*layoutBox.containingBlock())))
-    , m_absoluteDisplayBox(FormattingContext::mapBoxToAncestor(floatingState.layoutContext(), layoutBox, downcast<Container>(floatingState.root())))
-    , m_containingBlockAbsoluteDisplayBox(FormattingContext::mapBoxToAncestor(floatingState.layoutContext(), *m_containingBlock, downcast<Container>(floatingState.root())))
-{
-}
-
-FloatingState::FloatingState(LayoutContext& layoutContext, const Box& formattingContextRoot)
-    : m_layoutContext(layoutContext)
-    , m_formattingContextRoot(makeWeakPtr(const_cast<Box&>(formattingContextRoot)))
-{
-}
-
-#ifndef NDEBUG
-static bool belongsToThisFloatingContext(const Box& layoutBox, const Box& floatingStateRoot)
-{
-    auto& formattingContextRoot = layoutBox.formattingContextRoot();
-    if (&formattingContextRoot == &floatingStateRoot)
-        return true;
-
-    // Maybe the layout box belongs to an inline formatting context that inherits the floating state from the parent (block) formatting context. 
-    if (!formattingContextRoot.establishesInlineFormattingContext())
-        return false;
-
-    return &formattingContextRoot.formattingContextRoot() == &floatingStateRoot;
-}
-#endif
-
-void FloatingState::remove(const Box& layoutBox)
-{
-    for (size_t index = 0; index < m_floats.size(); ++index) {
-        if (&m_floats[index].layoutBox() == &layoutBox) {
-            m_floats.remove(index);
-            return;
-        }
-    }
-    ASSERT_NOT_REACHED();
-}
-
-void FloatingState::append(const Box& layoutBox)
-{
-    ASSERT(is<Container>(*m_formattingContextRoot));
-    ASSERT(belongsToThisFloatingContext(layoutBox, *m_formattingContextRoot));
-
-    // Floating state should hold boxes with computed position/size.
-    ASSERT(m_layoutContext.displayBoxForLayoutBox(layoutBox));
-    ASSERT(is<Container>(*m_formattingContextRoot));
-
-    m_floats.append({ layoutBox, *this });
-}
-
-std::optional<LayoutUnit> FloatingState::bottom(const Box& formattingContextRoot, Clear type) const
-{
-    if (m_floats.isEmpty())
-        return { };
-
-    // TODO: Currently this is only called once for each formatting context root with floats per layout.
-    // Cache the value if we end up calling it more frequently (and update it at append/remove).
-    std::optional<LayoutUnit> bottom;
-    for (auto& floatItem : m_floats) {
-        // Ignore floats from other formatting contexts when the floating state is inherited.
-        if (&formattingContextRoot != &floatItem.layoutBox().formattingContextRoot())
-            continue;
-
-        if ((type == Clear::Left && !floatItem.layoutBox().isLeftFloatingPositioned())
-            || (type == Clear::Right && !floatItem.layoutBox().isRightFloatingPositioned()))
-            continue;
-
-        auto floatsBottom = floatItem.displayBox().rectWithMargin().bottom();
-        if (bottom) {
-            bottom = std::max(*bottom, floatsBottom);
-            continue;
-        }
-        bottom = floatsBottom;
-    }
-    return bottom;
-}
-
-}
-}
-#endif

Deleted: trunk/Source/WebCore/layout/FloatingState.h (235177 => 235178)


--- trunk/Source/WebCore/layout/FloatingState.h	2018-08-22 16:55:19 UTC (rev 235177)
+++ trunk/Source/WebCore/layout/FloatingState.h	2018-08-22 17:10:34 UTC (rev 235178)
@@ -1,111 +0,0 @@
-/*
- * 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 "DisplayBox.h"
-#include <wtf/IsoMalloc.h>
-#include <wtf/Ref.h>
-#include <wtf/WeakPtr.h>
-
-namespace WebCore {
-
-namespace Layout {
-
-class Box;
-class Container;
-class FormattingState;
-class LayoutContext;
-
-// FloatingState holds the floating boxes per formatting context.
-class FloatingState : public RefCounted<FloatingState> {
-    WTF_MAKE_ISO_ALLOCATED(FloatingState);
-public:
-    static Ref<FloatingState> create(LayoutContext& layoutContext, const Box& formattingContextRoot) { return adoptRef(*new FloatingState(layoutContext, formattingContextRoot)); }
-
-    void append(const Box& layoutBox);
-    void remove(const Box& layoutBox);
-
-    bool isEmpty() const { return m_floats.isEmpty(); }
-
-    std::optional<LayoutUnit> leftBottom(const Box& formattingContextRoot) const;
-    std::optional<LayoutUnit> rightBottom(const Box& formattingContextRoot) const;
-    std::optional<LayoutUnit> bottom(const Box& formattingContextRoot) const;
-
-    class FloatItem {
-    public:
-        FloatItem(const Box&, const FloatingState&);
-
-        const Box& layoutBox() const { return *m_layoutBox; }
-        const Container& containingBlock() const { return *m_containingBlock; }
-
-        const Display::Box& displayBox() const { return m_absoluteDisplayBox; }
-        const Display::Box& containingBlockDisplayBox() const { return m_containingBlockAbsoluteDisplayBox; }
-
-    private:
-        WeakPtr<Box> m_layoutBox;
-        WeakPtr<Container> m_containingBlock;
-
-        Display::Box m_absoluteDisplayBox;
-        Display::Box m_containingBlockAbsoluteDisplayBox;
-    };
-    using FloatList = Vector<FloatItem>;
-    const FloatList& floats() const { return m_floats; }
-    const FloatItem* last() const { return isEmpty() ? nullptr : &m_floats.last(); }
-
-private:
-    friend class FloatingContext;
-    FloatingState(LayoutContext&, const Box& formattingContextRoot);
-
-    LayoutContext& layoutContext() const { return m_layoutContext; }
-    const Box& root() const { return *m_formattingContextRoot; }
-
-    std::optional<LayoutUnit> bottom(const Box& formattingContextRoot, Clear) const;
-
-    LayoutContext& m_layoutContext;
-    WeakPtr<Box> m_formattingContextRoot;
-    FloatList m_floats;
-};
-
-inline std::optional<LayoutUnit> FloatingState::leftBottom(const Box& formattingContextRoot) const
-{ 
-    return bottom(formattingContextRoot, Clear::Left);
-}
-
-inline std::optional<LayoutUnit> FloatingState::rightBottom(const Box& formattingContextRoot) const
-{
-    return bottom(formattingContextRoot, Clear::Right);
-}
-
-inline std::optional<LayoutUnit> FloatingState::bottom(const Box& formattingContextRoot) const
-{
-    return bottom(formattingContextRoot, Clear::Both);
-}
-
-}
-}
-#endif

Modified: trunk/Source/WebCore/layout/FormattingContextGeometry.cpp (235177 => 235178)


--- trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2018-08-22 16:55:19 UTC (rev 235177)
+++ trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2018-08-22 17:10:34 UTC (rev 235178)
@@ -24,12 +24,13 @@
  */
 
 #include "config.h"
-#include "FloatingState.h"
 #include "FormattingContext.h"
-#include "FormattingState.h"
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "FloatingState.h"
+#include "FormattingState.h"
+
 namespace WebCore {
 namespace Layout {
 

Copied: trunk/Source/WebCore/layout/floats/FloatingContext.cpp (from rev 235177, trunk/Source/WebCore/layout/FloatingContext.cpp) (0 => 235178)


--- trunk/Source/WebCore/layout/floats/FloatingContext.cpp	                        (rev 0)
+++ trunk/Source/WebCore/layout/floats/FloatingContext.cpp	2018-08-22 17:10:34 UTC (rev 235178)
@@ -0,0 +1,516 @@
+/*
+ * 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 "FloatingContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "DisplayBox.h"
+#include "LayoutBox.h"
+#include "LayoutContainer.h"
+#include "LayoutContext.h"
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(FloatingContext);
+
+// Finding the top/left position for a new floating(F)
+//  ____  ____  _____               _______
+// |    || L2 ||     | <-----1---->|       |
+// |    ||____||  L3 |             |   R1  |
+// | L1 |      |_____|             |       |
+// |____| <-------------2--------->|       |
+//                                 |       |
+//                                 |_______|
+//
+// 1. Compute the initial vertical position for (F) -> (1)
+// 2. Find the corresponding floating pair (L3-R1)
+// 3. Align (F) horizontally with (L3-R1) depending whether (F) is left/right positioned
+// 4. Intersect (F) with (L3-R1)
+// 5. If (F) does not fit, find the next floating pair (L1-R1)
+// 6. Repeat until either (F) fits/no more floats.
+// Note that all coordinates are in the coordinate system of the formatting root.
+// The formatting root here is always the one that establishes the floating context (see inherited floating context).
+// (It simply means that the float box's formatting root is not necessarily the same as the FormattingContext's root.)
+
+class Iterator;
+
+class FloatingPair {
+public:
+    bool isEmpty() const { return !m_leftIndex && !m_rightIndex; }
+    const Display::Box* left() const;
+    const Display::Box* right() const;
+    bool intersects(const Display::Box::Rect&) const;
+    LayoutUnit verticalPosition() const { return m_verticalPosition; }
+    LayoutUnit bottom() const;
+    bool operator==(const FloatingPair&) const;
+
+private:
+    friend class Iterator;
+    FloatingPair(const FloatingState::FloatList&);
+
+    const FloatingState::FloatList& m_floats;
+
+    std::optional<unsigned> m_leftIndex;
+    std::optional<unsigned> m_rightIndex;
+    LayoutUnit m_verticalPosition;
+};
+
+class Iterator {
+public:
+    Iterator(const FloatingState::FloatList&, std::optional<LayoutUnit> verticalPosition);
+
+    const FloatingPair& operator*() const { return m_current; }
+    Iterator& operator++();
+    bool operator==(const Iterator&) const;
+    bool operator!=(const Iterator&) const;
+
+private:
+    void set(LayoutUnit verticalPosition);
+
+    const FloatingState::FloatList& m_floats;
+    FloatingPair m_current;
+};
+
+static Iterator begin(const FloatingState& floatingState, LayoutUnit initialVerticalPosition)
+{
+    // Start with the inner-most floating pair for the initial vertical position.
+    return Iterator(floatingState.floats(), initialVerticalPosition);
+}
+
+static Iterator end(const FloatingState& floatingState)
+{
+    return Iterator(floatingState.floats(), std::nullopt);
+}
+
+FloatingContext::FloatingContext(FloatingState& floatingState)
+    : m_floatingState(floatingState)
+{
+}
+
+Position FloatingContext::positionForFloat(const Box& layoutBox) const
+{
+    ASSERT(layoutBox.isFloatingPositioned());
+    FloatingState::FloatItem floatItem = { layoutBox, m_floatingState };
+
+    Position floatPosition;
+    if (m_floatingState.isEmpty()) {
+        // No float box on the context yet -> align it with the containing block's left/right edge.
+        auto& displayBox = floatItem.displayBox();
+        floatPosition = { alignWithContainingBlock(floatItem) + displayBox.marginLeft(), displayBox.top() };
+    } else {
+        // Find the top most position where the float box fits.
+        floatPosition = floatingPosition(floatItem);
+    }
+
+    return toContainingBlock(floatItem, floatPosition);
+}
+
+std::optional<LayoutUnit> FloatingContext::verticalPositionWithClearance(const Box& layoutBox) const
+{
+    ASSERT(layoutBox.hasFloatClear());
+    ASSERT(layoutBox.isBlockLevelBox());
+
+    if (m_floatingState.isEmpty())
+        return { };
+
+    auto bottom = [&](std::optional<LayoutUnit> floatBottom) -> std::optional<LayoutUnit> {
+        // 'bottom' is in the formatting root's coordinate system.
+        if (!floatBottom)
+            return { };
+
+        // 9.5.2 Controlling flow next to floats: the 'clear' property
+        // Then the amount of clearance is set to the greater of:
+        //
+        // 1. The amount necessary to place the border edge of the block even with the bottom outer edge of the lowest float that is to be cleared.
+        // 2. The amount necessary to place the top border edge of the block at its hypothetical position.
+
+        auto& layoutContext = this->layoutContext();
+        auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+        auto rootRelativeTop = FormattingContext::mapTopLeftToAncestor(layoutContext, layoutBox, downcast<Container>(m_floatingState.root())).y;
+        auto clearance = *floatBottom - rootRelativeTop;
+        if (clearance <= 0)
+            return { };
+
+        // Clearance inhibits margin collapsing. Let's reset the relevant adjoining margins.
+        if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
+            auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
+
+            // Since the previous inflow sibling has already been laid out, its margin is collapsed by now.
+            ASSERT(!previousInFlowDisplayBox.marginBottom());
+            auto collapsedMargin = displayBox.marginTop();
+
+            // Reset previous bottom and current top margins to non-collapsing.
+            previousInFlowDisplayBox.setVerticalMargin({ previousInFlowDisplayBox.marginTop(), previousInFlowDisplayBox.nonCollapsedMarginBottom() });
+            displayBox.setVerticalMargin({ displayBox.nonCollapsedMarginTop(), displayBox.marginBottom() });
+
+            auto nonCollapsedMargin = previousInFlowDisplayBox.marginBottom() + displayBox.marginTop();
+            auto marginOffset = nonCollapsedMargin - collapsedMargin;
+            // Move the box to the position where it would be with non-collapsed margins.
+            rootRelativeTop += marginOffset;
+
+            // Having negative clearance is also normal. It just means that the box with the non-collapsed margins is now lower than it needs to be.
+            clearance -= marginOffset;
+        }
+        // Now adjust the box's position with the clearance.
+        rootRelativeTop += clearance;
+        ASSERT(*floatBottom == rootRelativeTop);
+
+        // The return vertical position is in the containing block's coordinate system.
+        auto containingBlockRootRelativeTop = FormattingContext::mapTopLeftToAncestor(layoutContext, *layoutBox.containingBlock(), downcast<Container>(m_floatingState.root())).y;
+        return rootRelativeTop - containingBlockRootRelativeTop;
+    };
+
+    auto clear = layoutBox.style().clear();
+    auto& formattingContextRoot = layoutBox.formattingContextRoot();
+
+    if (clear == Clear::Left)
+        return bottom(m_floatingState.leftBottom(formattingContextRoot));
+
+    if (clear == Clear::Right)
+        return bottom(m_floatingState.rightBottom(formattingContextRoot));
+
+    if (clear == Clear::Both)
+        return bottom(m_floatingState.bottom(formattingContextRoot));
+
+    ASSERT_NOT_REACHED();
+    return { };
+}
+
+Position FloatingContext::floatingPosition(const FloatingState::FloatItem& floatItem) const
+{
+    auto initialVerticalPosition = this->initialVerticalPosition(floatItem);
+    auto& displayBox = floatItem.displayBox();
+    auto marginBoxSize = displayBox.marginBox().size();
+
+    auto end = Layout::end(m_floatingState);
+    auto top = initialVerticalPosition;
+    auto bottomMost = top;
+    for (auto iterator = begin(m_floatingState, initialVerticalPosition); iterator != end; ++iterator) {
+        ASSERT(!(*iterator).isEmpty());
+
+        auto floats = *iterator;
+        top = floats.verticalPosition();
+
+        // Move the box horizontally so that it aligns with the current floating pair.
+        auto left = alignWithFloatings(floats, floatItem);
+        // Check if the box fits at this vertical position.
+        if (!floats.intersects({ top, left, marginBoxSize.width(), marginBoxSize.height() }))
+            return { left + displayBox.marginLeft(), top + displayBox.marginTop() };
+
+        bottomMost = floats.bottom();
+        // Move to the next floating pair.
+    }
+
+    // Passed all the floats and still does not fit?
+    return { alignWithContainingBlock(floatItem) + displayBox.marginLeft(), bottomMost + displayBox.marginTop() };
+}
+
+LayoutUnit FloatingContext::initialVerticalPosition(const FloatingState::FloatItem& floatItem) const
+{
+    // Incoming floating cannot be placed higher than existing floats.
+    // Take the static position (where the box would go if it wasn't floating) and adjust it with the last floating.
+    auto marginBoxTop = floatItem.displayBox().rectWithMargin().top();
+
+    if (auto lastFloat = m_floatingState.last())
+        return std::max(marginBoxTop, lastFloat->displayBox().rectWithMargin().top());
+
+    return marginBoxTop;
+}
+
+LayoutUnit FloatingContext::alignWithContainingBlock(const FloatingState::FloatItem& floatItem) const
+{
+    // If there is no floating to align with, push the box to the left/right edge of its containing block's content box.
+    // (Either there's no floats at all or this box does not fit at any vertical positions where the floats are.)
+    auto& containingBlockDisplayBox = floatItem.containingBlockDisplayBox();
+    auto containingBlockContentBoxLeft = containingBlockDisplayBox.left() + containingBlockDisplayBox.contentBoxLeft();
+
+    if (floatItem.layoutBox().isLeftFloatingPositioned())
+        return containingBlockContentBoxLeft;
+
+    return containingBlockContentBoxLeft + containingBlockDisplayBox.contentBoxWidth() - floatItem.displayBox().marginBox().width();
+}
+
+LayoutUnit FloatingContext::alignWithFloatings(const FloatingPair& floatingPair, const FloatingState::FloatItem& floatItem) const
+{
+    // Compute the horizontal position for the new floating by taking both the contining block and the current left/right floats into account.
+    auto& containingBlockDisplayBox = floatItem.containingBlockDisplayBox();
+    auto containingBlockContentBoxLeft = containingBlockDisplayBox.left() + containingBlockDisplayBox.contentBoxLeft();
+    auto containingBlockContentBoxRight = containingBlockDisplayBox.left() + containingBlockDisplayBox.contentBoxRight();
+    auto marginBoxWidth = floatItem.displayBox().marginBox().width();
+
+    auto leftAlignedBoxLeft = containingBlockContentBoxLeft;
+    auto rightAlignedBoxLeft = containingBlockContentBoxRight - marginBoxWidth;
+
+    if (floatingPair.isEmpty()) {
+        ASSERT_NOT_REACHED();
+        return floatItem.layoutBox().isLeftFloatingPositioned() ? leftAlignedBoxLeft : rightAlignedBoxLeft;
+    }
+
+    if (floatItem.layoutBox().isLeftFloatingPositioned()) {
+        if (auto* leftDisplayBox = floatingPair.left()) {
+            auto leftFloatingBoxRight = leftDisplayBox->rectWithMargin().right();
+            return std::min(std::max(leftAlignedBoxLeft, leftFloatingBoxRight), rightAlignedBoxLeft);
+        }
+        
+        return leftAlignedBoxLeft;
+    }
+
+    ASSERT(floatItem.layoutBox().isRightFloatingPositioned());
+
+    if (auto* rightDisplayBox = floatingPair.right()) {
+        auto rightFloatingBoxLeft = rightDisplayBox->rectWithMargin().left();
+        return std::max(std::min(rightAlignedBoxLeft, rightFloatingBoxLeft - marginBoxWidth), leftAlignedBoxLeft);
+    }
+
+    return rightAlignedBoxLeft;
+}
+
+// FIXME: find a better place for this.
+Position FloatingContext::toContainingBlock(const FloatingState::FloatItem& floatItem, Position position) const
+{
+    // From formatting root coordinate system back to containing block's.
+    if (&floatItem.containingBlock() == &m_floatingState.root())
+        return position;
+
+    auto& containingBlockDisplayBox = floatItem.containingBlockDisplayBox();
+    return { position.x - containingBlockDisplayBox.left(), position.y - containingBlockDisplayBox.top() };
+}
+
+FloatingPair::FloatingPair(const FloatingState::FloatList& floats)
+    : m_floats(floats)
+{
+}
+
+const Display::Box* FloatingPair::left() const
+{
+    if (!m_leftIndex)
+        return nullptr;
+
+    ASSERT(m_floats[*m_leftIndex].layoutBox().isLeftFloatingPositioned());
+    return &m_floats[*m_leftIndex].displayBox();
+}
+
+const Display::Box* FloatingPair::right() const
+{
+    if (!m_rightIndex)
+        return nullptr;
+
+    ASSERT(m_floats[*m_rightIndex].layoutBox().isRightFloatingPositioned());
+    return &m_floats[*m_rightIndex].displayBox();
+}
+
+bool FloatingPair::intersects(const Display::Box::Rect& candidateRect) const
+{
+    auto intersects = [&](const Display::Box* floating, Float floatingType) {
+        if (!floating)
+            return false;
+
+        auto marginRect = floating->rectWithMargin();
+        // Before intersecting, check if the candidate position is too far to the left/right.
+        // The new float's containing block could push the candidate position beyond the current float horizontally.
+        if ((floatingType == Float::Left && candidateRect.left() < marginRect.right())
+            || (floatingType == Float::Right && candidateRect.right() > marginRect.left()))
+            return true;
+        return marginRect.intersects(candidateRect);
+    };
+
+    if (!m_leftIndex && !m_rightIndex) {
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+    if (intersects(left(), Float::Left))
+        return true;
+
+    if (intersects(right(), Float::Right))
+        return true;
+
+    return false;
+}
+
+bool FloatingPair::operator ==(const FloatingPair& other) const
+{
+    return m_leftIndex == other.m_leftIndex && m_rightIndex == other.m_rightIndex;
+}
+
+LayoutUnit FloatingPair::bottom() const
+{
+    auto* left = this->left();
+    auto* right = this->right();
+    ASSERT(left || right);
+
+    auto leftBottom = left ? std::optional<LayoutUnit>(left->rectWithMargin().bottom()) : std::nullopt;
+    auto rightBottom = right ? std::optional<LayoutUnit>(right->rectWithMargin().bottom()) : std::nullopt;
+
+    if (leftBottom && rightBottom)
+        return std::max(*leftBottom, *rightBottom);
+
+    if (leftBottom)
+        return *leftBottom;
+
+    return *rightBottom;
+}
+
+Iterator::Iterator(const FloatingState::FloatList& floats, std::optional<LayoutUnit> verticalPosition)
+    : m_floats(floats)
+    , m_current(floats)
+{
+    if (verticalPosition)
+        set(*verticalPosition);
+}
+
+inline static std::optional<unsigned> previousFloatingIndex(Float floatingType, const FloatingState::FloatList& floats, unsigned currentIndex)
+{
+    RELEASE_ASSERT(currentIndex <= floats.size());
+
+    while (currentIndex) {
+        auto& floating = floats[--currentIndex].layoutBox();
+        if ((floatingType == Float::Left && floating.isLeftFloatingPositioned()) || (floatingType == Float::Right && floating.isRightFloatingPositioned()))
+            return currentIndex;
+    }
+
+    return { };
+}
+
+Iterator& Iterator::operator++()
+{
+    if (m_current.isEmpty()) {
+        ASSERT_NOT_REACHED();
+        return *this;
+    }
+
+    auto findPreviousFloatingWithLowerBottom = [&](Float floatingType, unsigned currentIndex) -> std::optional<unsigned> {
+
+        RELEASE_ASSERT(currentIndex < m_floats.size());
+
+        // Last floating? There's certainly no previous floating at this point.
+        if (!currentIndex)
+            return { };
+
+        auto currentBottom = m_floats[currentIndex].displayBox().rectWithMargin().bottom();
+
+        std::optional<unsigned> index = currentIndex;
+        while (true) {
+            index = previousFloatingIndex(floatingType, m_floats, *index);
+            if (!index)
+                return { };
+
+            if (m_floats[*index].displayBox().rectWithMargin().bottom() > currentBottom)
+                return index;
+        }
+
+        ASSERT_NOT_REACHED();
+        return { };
+    };
+
+    // 1. Take the current floating from left and right and check which one's bottom edge is positioned higher (they could be on the same vertical position too).
+    // The current floats from left and right are considered the inner-most pair for the current vertical position.
+    // 2. Move away from inner-most pair by picking one of the previous floats in the list(#1)
+    // Ensure that the new floating's bottom edge is positioned lower than the current one -which essentially means skipping in-between floats that are positioned higher).
+    // 3. Reset the vertical position and align it with the new left-right pair. These floats are now the inner-most boxes for the current vertical position.
+    // As the result we have more horizontal space on the current vertical position.
+    auto leftBottom = m_current.left() ? std::optional<LayoutUnit>(m_current.left()->bottom()) : std::nullopt;
+    auto rightBottom = m_current.right() ? std::optional<LayoutUnit>(m_current.right()->bottom()) : std::nullopt;
+
+    auto updateLeft = (leftBottom == rightBottom) || (!rightBottom || (leftBottom && leftBottom < rightBottom)); 
+    auto updateRight = (leftBottom == rightBottom) || (!leftBottom || (rightBottom && leftBottom > rightBottom)); 
+
+    if (updateLeft) {
+        ASSERT(m_current.m_leftIndex);
+        m_current.m_verticalPosition = *leftBottom;
+        m_current.m_leftIndex = findPreviousFloatingWithLowerBottom(Float::Left, *m_current.m_leftIndex);
+    }
+    
+    if (updateRight) {
+        ASSERT(m_current.m_rightIndex);
+        m_current.m_verticalPosition = *rightBottom;
+        m_current.m_rightIndex = findPreviousFloatingWithLowerBottom(Float::Right, *m_current.m_rightIndex);
+    }
+
+    return *this;
+}
+
+void Iterator::set(LayoutUnit verticalPosition)
+{
+    // Move the iterator to the initial vertical position by starting at the inner-most floating pair (last floats on left/right).
+    // 1. Check if the inner-most pair covers the vertical position.
+    // 2. Move outwards from the inner-most pair until the vertical postion intersects.
+    // (Note that verticalPosition has already been adjusted with the top of the last float.)
+
+    m_current.m_verticalPosition = verticalPosition;
+    // No floats at all?
+    if (m_floats.isEmpty()) {
+        ASSERT_NOT_REACHED();
+
+        m_current.m_leftIndex = { };
+        m_current.m_rightIndex = { };
+        return;
+    }
+
+    auto findFloatingBelow = [&](Float floatingType) -> std::optional<unsigned> {
+
+        ASSERT(!m_floats.isEmpty());
+
+        auto index = floatingType == Float::Left ? m_current.m_leftIndex : m_current.m_rightIndex;
+        // Start from the end if we don't have current yet.
+        index = index.value_or(m_floats.size());
+        while (true) {
+            index = previousFloatingIndex(floatingType, m_floats, *index);
+            if (!index)
+                return { };
+
+            auto bottom = m_floats[*index].displayBox().rectWithMargin().bottom();
+            // Is this floating intrusive on this position?
+            if (bottom > verticalPosition)
+                return index;
+        }
+
+        return { };
+    };
+
+    m_current.m_leftIndex = findFloatingBelow(Float::Left);
+    m_current.m_rightIndex = findFloatingBelow(Float::Right);
+
+    ASSERT(!m_current.m_leftIndex || (*m_current.m_leftIndex < m_floats.size() && m_floats[*m_current.m_leftIndex].layoutBox().isLeftFloatingPositioned()));
+    ASSERT(!m_current.m_rightIndex || (*m_current.m_rightIndex < m_floats.size() && m_floats[*m_current.m_rightIndex].layoutBox().isRightFloatingPositioned()));
+}
+
+bool Iterator::operator==(const Iterator& other) const
+{
+    return m_current == other.m_current;
+}
+
+bool Iterator::operator!=(const Iterator& other) const
+{
+    return !(*this == other);
+}
+
+}
+}
+#endif

Copied: trunk/Source/WebCore/layout/floats/FloatingContext.h (from rev 235177, trunk/Source/WebCore/layout/FloatingContext.h) (0 => 235178)


--- trunk/Source/WebCore/layout/floats/FloatingContext.h	                        (rev 0)
+++ trunk/Source/WebCore/layout/floats/FloatingContext.h	2018-08-22 17:10:34 UTC (rev 235178)
@@ -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.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "FloatingState.h"
+#include "LayoutUnits.h"
+#include <wtf/IsoMalloc.h>
+
+namespace WebCore {
+
+namespace Layout {
+
+class Box;
+class Container;
+class FloatingPair;
+class LayoutContext;
+
+// FloatingContext is responsible for adjusting the position of a box in the current formatting context
+// by taking the floating boxes into account.
+class FloatingContext {
+    WTF_MAKE_ISO_ALLOCATED(FloatingContext);
+public:
+    FloatingContext(FloatingState&);
+
+    FloatingState& floatingState() const { return m_floatingState; }
+
+    Position positionForFloat(const Box&) const;
+    std::optional<LayoutUnit> verticalPositionWithClearance(const Box&) const;
+
+private:
+    LayoutContext& layoutContext() const { return m_floatingState.layoutContext(); }
+
+    Position floatingPosition(const FloatingState::FloatItem&) const;
+
+    LayoutUnit initialVerticalPosition(const FloatingState::FloatItem&) const;
+    LayoutUnit alignWithContainingBlock(const FloatingState::FloatItem&) const;
+    LayoutUnit alignWithFloatings(const FloatingPair&, const FloatingState::FloatItem&) const;
+    Position toContainingBlock(const FloatingState::FloatItem&, Position) const;
+
+    FloatingState& m_floatingState;
+};
+
+}
+}
+#endif

Copied: trunk/Source/WebCore/layout/floats/FloatingState.cpp (from rev 235177, trunk/Source/WebCore/layout/FloatingState.cpp) (0 => 235178)


--- trunk/Source/WebCore/layout/floats/FloatingState.cpp	                        (rev 0)
+++ trunk/Source/WebCore/layout/floats/FloatingState.cpp	2018-08-22 17:10:34 UTC (rev 235178)
@@ -0,0 +1,123 @@
+/*
+ * 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 "FloatingState.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "FormattingContext.h"
+#include "LayoutBox.h"
+#include "LayoutContainer.h"
+#include "LayoutContext.h"
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(FloatingState);
+
+FloatingState::FloatItem::FloatItem(const Box& layoutBox, const FloatingState& floatingState)
+    : m_layoutBox(makeWeakPtr(const_cast<Box&>(layoutBox)))
+    , m_containingBlock(makeWeakPtr(const_cast<Container&>(*layoutBox.containingBlock())))
+    , m_absoluteDisplayBox(FormattingContext::mapBoxToAncestor(floatingState.layoutContext(), layoutBox, downcast<Container>(floatingState.root())))
+    , m_containingBlockAbsoluteDisplayBox(FormattingContext::mapBoxToAncestor(floatingState.layoutContext(), *m_containingBlock, downcast<Container>(floatingState.root())))
+{
+}
+
+FloatingState::FloatingState(LayoutContext& layoutContext, const Box& formattingContextRoot)
+    : m_layoutContext(layoutContext)
+    , m_formattingContextRoot(makeWeakPtr(const_cast<Box&>(formattingContextRoot)))
+{
+}
+
+#ifndef NDEBUG
+static bool belongsToThisFloatingContext(const Box& layoutBox, const Box& floatingStateRoot)
+{
+    auto& formattingContextRoot = layoutBox.formattingContextRoot();
+    if (&formattingContextRoot == &floatingStateRoot)
+        return true;
+
+    // Maybe the layout box belongs to an inline formatting context that inherits the floating state from the parent (block) formatting context. 
+    if (!formattingContextRoot.establishesInlineFormattingContext())
+        return false;
+
+    return &formattingContextRoot.formattingContextRoot() == &floatingStateRoot;
+}
+#endif
+
+void FloatingState::remove(const Box& layoutBox)
+{
+    for (size_t index = 0; index < m_floats.size(); ++index) {
+        if (&m_floats[index].layoutBox() == &layoutBox) {
+            m_floats.remove(index);
+            return;
+        }
+    }
+    ASSERT_NOT_REACHED();
+}
+
+void FloatingState::append(const Box& layoutBox)
+{
+    ASSERT(is<Container>(*m_formattingContextRoot));
+    ASSERT(belongsToThisFloatingContext(layoutBox, *m_formattingContextRoot));
+
+    // Floating state should hold boxes with computed position/size.
+    ASSERT(m_layoutContext.displayBoxForLayoutBox(layoutBox));
+    ASSERT(is<Container>(*m_formattingContextRoot));
+
+    m_floats.append({ layoutBox, *this });
+}
+
+std::optional<LayoutUnit> FloatingState::bottom(const Box& formattingContextRoot, Clear type) const
+{
+    if (m_floats.isEmpty())
+        return { };
+
+    // TODO: Currently this is only called once for each formatting context root with floats per layout.
+    // Cache the value if we end up calling it more frequently (and update it at append/remove).
+    std::optional<LayoutUnit> bottom;
+    for (auto& floatItem : m_floats) {
+        // Ignore floats from other formatting contexts when the floating state is inherited.
+        if (&formattingContextRoot != &floatItem.layoutBox().formattingContextRoot())
+            continue;
+
+        if ((type == Clear::Left && !floatItem.layoutBox().isLeftFloatingPositioned())
+            || (type == Clear::Right && !floatItem.layoutBox().isRightFloatingPositioned()))
+            continue;
+
+        auto floatsBottom = floatItem.displayBox().rectWithMargin().bottom();
+        if (bottom) {
+            bottom = std::max(*bottom, floatsBottom);
+            continue;
+        }
+        bottom = floatsBottom;
+    }
+    return bottom;
+}
+
+}
+}
+#endif

Copied: trunk/Source/WebCore/layout/floats/FloatingState.h (from rev 235177, trunk/Source/WebCore/layout/FloatingState.h) (0 => 235178)


--- trunk/Source/WebCore/layout/floats/FloatingState.h	                        (rev 0)
+++ trunk/Source/WebCore/layout/floats/FloatingState.h	2018-08-22 17:10:34 UTC (rev 235178)
@@ -0,0 +1,111 @@
+/*
+ * 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 "DisplayBox.h"
+#include <wtf/IsoMalloc.h>
+#include <wtf/Ref.h>
+#include <wtf/WeakPtr.h>
+
+namespace WebCore {
+
+namespace Layout {
+
+class Box;
+class Container;
+class FormattingState;
+class LayoutContext;
+
+// FloatingState holds the floating boxes per formatting context.
+class FloatingState : public RefCounted<FloatingState> {
+    WTF_MAKE_ISO_ALLOCATED(FloatingState);
+public:
+    static Ref<FloatingState> create(LayoutContext& layoutContext, const Box& formattingContextRoot) { return adoptRef(*new FloatingState(layoutContext, formattingContextRoot)); }
+
+    void append(const Box& layoutBox);
+    void remove(const Box& layoutBox);
+
+    bool isEmpty() const { return m_floats.isEmpty(); }
+
+    std::optional<LayoutUnit> leftBottom(const Box& formattingContextRoot) const;
+    std::optional<LayoutUnit> rightBottom(const Box& formattingContextRoot) const;
+    std::optional<LayoutUnit> bottom(const Box& formattingContextRoot) const;
+
+    class FloatItem {
+    public:
+        FloatItem(const Box&, const FloatingState&);
+
+        const Box& layoutBox() const { return *m_layoutBox; }
+        const Container& containingBlock() const { return *m_containingBlock; }
+
+        const Display::Box& displayBox() const { return m_absoluteDisplayBox; }
+        const Display::Box& containingBlockDisplayBox() const { return m_containingBlockAbsoluteDisplayBox; }
+
+    private:
+        WeakPtr<Box> m_layoutBox;
+        WeakPtr<Container> m_containingBlock;
+
+        Display::Box m_absoluteDisplayBox;
+        Display::Box m_containingBlockAbsoluteDisplayBox;
+    };
+    using FloatList = Vector<FloatItem>;
+    const FloatList& floats() const { return m_floats; }
+    const FloatItem* last() const { return isEmpty() ? nullptr : &m_floats.last(); }
+
+private:
+    friend class FloatingContext;
+    FloatingState(LayoutContext&, const Box& formattingContextRoot);
+
+    LayoutContext& layoutContext() const { return m_layoutContext; }
+    const Box& root() const { return *m_formattingContextRoot; }
+
+    std::optional<LayoutUnit> bottom(const Box& formattingContextRoot, Clear) const;
+
+    LayoutContext& m_layoutContext;
+    WeakPtr<Box> m_formattingContextRoot;
+    FloatList m_floats;
+};
+
+inline std::optional<LayoutUnit> FloatingState::leftBottom(const Box& formattingContextRoot) const
+{ 
+    return bottom(formattingContextRoot, Clear::Left);
+}
+
+inline std::optional<LayoutUnit> FloatingState::rightBottom(const Box& formattingContextRoot) const
+{
+    return bottom(formattingContextRoot, Clear::Right);
+}
+
+inline std::optional<LayoutUnit> FloatingState::bottom(const Box& formattingContextRoot) const
+{
+    return bottom(formattingContextRoot, Clear::Both);
+}
+
+}
+}
+#endif
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to