Use "= default" to denote default constructor or destructor
[WebKit-https.git] / Source / WebCore / rendering / FloatingObjects.cpp
index 4a04ade..a8d040d 100644 (file)
 #include "RenderBox.h"
 #include "RenderView.h"
 
-using namespace std;
-using namespace WTF;
 
 namespace WebCore {
+using namespace WTF;
 
 struct SameSizeAsFloatingObject {
     void* pointers[2];
     LayoutRect rect;
     int paginationStrut;
+    LayoutSize size;
     uint32_t bitfields : 8;
 };
 
@@ -44,8 +44,6 @@ COMPILE_ASSERT(sizeof(FloatingObject) == sizeof(SameSizeAsFloatingObject), Float
 
 FloatingObject::FloatingObject(RenderBox& renderer)
     : m_renderer(renderer)
-    , m_originatingLine(nullptr)
-    , m_paginationStrut(0)
     , m_shouldPaint(true)
     , m_isDescendant(false)
     , m_isPlaced(false)
@@ -61,11 +59,10 @@ FloatingObject::FloatingObject(RenderBox& renderer)
         m_type = FloatRight;
 }
 
-FloatingObject::FloatingObject(RenderBox& renderer, Type type, const LayoutRect& frameRect, bool shouldPaint, bool isDescendant)
+FloatingObject::FloatingObject(RenderBox& renderer, Type type, const LayoutRect& frameRect, const LayoutSize& marginOffset, bool shouldPaint, bool isDescendant)
     : m_renderer(renderer)
-    , m_originatingLine(nullptr)
     , m_frameRect(frameRect)
-    , m_paginationStrut(0)
+    , m_marginOffset(marginOffset)
     , m_type(type)
     , m_shouldPaint(shouldPaint)
     , m_isDescendant(isDescendant)
@@ -86,21 +83,23 @@ std::unique_ptr<FloatingObject> FloatingObject::create(RenderBox& renderer)
 
 std::unique_ptr<FloatingObject> FloatingObject::copyToNewContainer(LayoutSize offset, bool shouldPaint, bool isDescendant) const
 {
-    // FIXME: Use make_unique here, once we can get it to compile on all platforms we support.
-    return std::unique_ptr<FloatingObject>(new FloatingObject(renderer(), type(), LayoutRect(frameRect().location() - offset, frameRect().size()), shouldPaint, isDescendant));
+    return std::make_unique<FloatingObject>(renderer(), type(), LayoutRect(frameRect().location() - offset, frameRect().size()), marginOffset(), shouldPaint, isDescendant);
 }
 
-std::unique_ptr<FloatingObject> FloatingObject::unsafeClone() const
+std::unique_ptr<FloatingObject> FloatingObject::cloneForNewParent() const
 {
-    // FIXME: Use make_unique here, once we can get it to compile on all platforms we support.
-    std::unique_ptr<FloatingObject> cloneObject(new FloatingObject(renderer(), type(), m_frameRect, m_shouldPaint, m_isDescendant));
-    cloneObject->m_originatingLine = m_originatingLine;
+    auto cloneObject = std::make_unique<FloatingObject>(renderer(), type(), m_frameRect, m_marginOffset, m_shouldPaint, m_isDescendant);
     cloneObject->m_paginationStrut = m_paginationStrut;
     cloneObject->m_isPlaced = m_isPlaced;
     return cloneObject;
 }
 
-inline static bool rangesIntersect(int floatTop, int floatBottom, int objectTop, int objectBottom)
+LayoutSize FloatingObject::translationOffsetToAncestor() const
+{
+    return locationOffsetOfBorderBox() - renderer().locationOffset();
+}
+
+inline static bool rangesIntersect(LayoutUnit floatTop, LayoutUnit floatBottom, LayoutUnit objectTop, LayoutUnit objectBottom)
 {
     if (objectTop >= floatBottom || objectBottom < floatTop)
         return false;
@@ -125,128 +124,151 @@ class ComputeFloatOffsetAdapter {
 public:
     typedef FloatingObjectInterval IntervalType;
 
-    ComputeFloatOffsetAdapter(const RenderBlockFlow* renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
+    ComputeFloatOffsetAdapter(const RenderBlockFlow& renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
         : m_renderer(renderer)
-        , m_lineTop(roundToInt(lineTop))
-        , m_lineBottom(roundToInt(lineBottom))
+        , m_lineTop(lineTop)
+        , m_lineBottom(lineBottom)
         , m_offset(offset)
         , m_outermostFloat(0)
     {
     }
 
-    int lowValue() const { return m_lineTop; }
-    int highValue() const { return m_lineBottom; }
+    virtual ~ComputeFloatOffsetAdapter() = default;
+
+    LayoutUnit lowValue() const { return m_lineTop; }
+    LayoutUnit highValue() const { return m_lineBottom; }
     void collectIfNeeded(const IntervalType&);
 
     LayoutUnit offset() const { return m_offset; }
-    LayoutUnit shapeOffset() const;
-    LayoutUnit heightRemaining() const;
 
-private:
-    bool updateOffsetIfNeeded(const FloatingObject*);
+protected:
+    virtual bool updateOffsetIfNeeded(const FloatingObject&) = 0;
 
-    const RenderBlockFlow* m_renderer;
-    int m_lineTop;
-    int m_lineBottom;
+    const RenderBlockFlow& m_renderer;
+    LayoutUnit m_lineTop;
+    LayoutUnit m_lineBottom;
     LayoutUnit m_offset;
     const FloatingObject* m_outermostFloat;
 };
 
+template <FloatingObject::Type FloatTypeValue>
+class ComputeFloatOffsetForFloatLayoutAdapter : public ComputeFloatOffsetAdapter<FloatTypeValue> {
+public:
+    ComputeFloatOffsetForFloatLayoutAdapter(const RenderBlockFlow& renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
+        : ComputeFloatOffsetAdapter<FloatTypeValue>(renderer, lineTop, lineBottom, offset)
+    {
+    }
+
+    virtual ~ComputeFloatOffsetForFloatLayoutAdapter() = default;
+
+    LayoutUnit heightRemaining() const;
+
+protected:
+    bool updateOffsetIfNeeded(const FloatingObject&) final;
+};
+
+template <FloatingObject::Type FloatTypeValue>
+class ComputeFloatOffsetForLineLayoutAdapter : public ComputeFloatOffsetAdapter<FloatTypeValue> {
+public:
+    ComputeFloatOffsetForLineLayoutAdapter(const RenderBlockFlow& renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
+        : ComputeFloatOffsetAdapter<FloatTypeValue>(renderer, lineTop, lineBottom, offset)
+    {
+    }
+
+    virtual ~ComputeFloatOffsetForLineLayoutAdapter() = default;
+
+protected:
+    bool updateOffsetIfNeeded(const FloatingObject&) final;
+};
+
 class FindNextFloatLogicalBottomAdapter {
 public:
     typedef FloatingObjectInterval IntervalType;
 
     FindNextFloatLogicalBottomAdapter(const RenderBlockFlow& renderer, LayoutUnit belowLogicalHeight)
         : m_renderer(renderer)
-        , m_belowLogicalHeight(floorToInt(belowLogicalHeight))
-        , m_aboveLogicalHeight(roundToInt(LayoutUnit::max()))
-        , m_nextLogicalBottom(LayoutUnit::max())
-        , m_nextShapeLogicalBottom(LayoutUnit::max())
+        , m_belowLogicalHeight(belowLogicalHeight)
     {
     }
 
-    int lowValue() const { return m_belowLogicalHeight; }
-    int highValue() const { return m_aboveLogicalHeight; }
+    LayoutUnit lowValue() const { return m_belowLogicalHeight; }
+    LayoutUnit highValue() const { return LayoutUnit::max(); }
     void collectIfNeeded(const IntervalType&);
 
-    LayoutUnit nextLogicalBottom() { return m_nextLogicalBottom == LayoutUnit::max() ? LayoutUnit() : m_nextLogicalBottom; }
-    LayoutUnit nextShapeLogicalBottom() { return m_nextShapeLogicalBottom == LayoutUnit::max() ? nextLogicalBottom() : m_nextShapeLogicalBottom; }
+    LayoutUnit nextLogicalBottom() const { return m_nextLogicalBottom.value_or(0); }
+    LayoutUnit nextShapeLogicalBottom() const { return m_nextShapeLogicalBottom.value_or(nextLogicalBottom()); }
 
 private:
     const RenderBlockFlow& m_renderer;
-    int m_belowLogicalHeight;
-    int m_aboveLogicalHeight;
-    LayoutUnit m_nextLogicalBottom;
-    LayoutUnit m_nextShapeLogicalBottom;
+    LayoutUnit m_belowLogicalHeight;
+    std::optional<LayoutUnit> m_nextLogicalBottom;
+    std::optional<LayoutUnit> m_nextShapeLogicalBottom;
 };
 
 inline void FindNextFloatLogicalBottomAdapter::collectIfNeeded(const IntervalType& interval)
 {
-    const FloatingObject* floatingObject = interval.data();
-    if (!rangesIntersect(interval.low(), interval.high(), m_belowLogicalHeight, m_aboveLogicalHeight))
+    const auto& floatingObject = *interval.data();
+    if (!rangesIntersect(interval.low(), interval.high(), m_belowLogicalHeight, LayoutUnit::max()))
         return;
 
     // All the objects returned from the tree should be already placed.
-    ASSERT(floatingObject->isPlaced());
-    ASSERT(rangesIntersect(m_renderer.pixelSnappedLogicalTopForFloat(floatingObject), m_renderer.pixelSnappedLogicalBottomForFloat(floatingObject), m_belowLogicalHeight, m_aboveLogicalHeight));
+    ASSERT(floatingObject.isPlaced());
+    ASSERT(rangesIntersect(m_renderer.logicalTopForFloat(floatingObject), m_renderer.logicalBottomForFloat(floatingObject), m_belowLogicalHeight, LayoutUnit::max()));
 
     LayoutUnit floatBottom = m_renderer.logicalBottomForFloat(floatingObject);
-    if (m_nextLogicalBottom < floatBottom)
+    if (m_nextLogicalBottom && m_nextLogicalBottom.value() < floatBottom)
         return;
 
-#if ENABLE(CSS_SHAPES)
-    if (ShapeOutsideInfo* shapeOutside = floatingObject->renderer().shapeOutsideInfo()) {
-        LayoutUnit shapeBottom = m_renderer.logicalTopForFloat(floatingObject) + m_renderer.marginBeforeForChild(floatingObject->renderer()) + shapeOutside->shapeLogicalBottom();
+    if (ShapeOutsideInfo* shapeOutside = floatingObject.renderer().shapeOutsideInfo()) {
+        LayoutUnit shapeBottom = m_renderer.logicalTopForFloat(floatingObject) + m_renderer.marginBeforeForChild(floatingObject.renderer()) + shapeOutside->shapeLogicalBottom();
         // Use the shapeBottom unless it extends outside of the margin box, in which case it is clipped.
-        m_nextShapeLogicalBottom = min(shapeBottom, floatBottom);
+        m_nextShapeLogicalBottom = std::min(shapeBottom, floatBottom);
     } else
         m_nextShapeLogicalBottom = floatBottom;
-#endif
     m_nextLogicalBottom = floatBottom;
 }
 
 LayoutUnit FloatingObjects::findNextFloatLogicalBottomBelow(LayoutUnit logicalHeight)
 {
-    FindNextFloatLogicalBottomAdapter adapter(*m_renderer, logicalHeight);
-    placedFloatsTree().allOverlapsWithAdapter(adapter);
+    FindNextFloatLogicalBottomAdapter adapter(m_renderer, logicalHeight);
+    if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree())
+        placedFloatsTree->allOverlapsWithAdapter(adapter);
 
     return adapter.nextShapeLogicalBottom();
 }
 
 LayoutUnit FloatingObjects::findNextFloatLogicalBottomBelowForBlock(LayoutUnit logicalHeight)
 {
-    FindNextFloatLogicalBottomAdapter adapter(*m_renderer, logicalHeight);
-    placedFloatsTree().allOverlapsWithAdapter(adapter);
+    FindNextFloatLogicalBottomAdapter adapter(m_renderer, logicalHeight);
+    if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree())
+        placedFloatsTree->allOverlapsWithAdapter(adapter);
 
     return adapter.nextLogicalBottom();
 }
 
-FloatingObjects::FloatingObjects(const RenderBlockFlow* renderer, bool horizontalWritingMode)
-    : m_placedFloatsTree(UninitializedTree)
-    , m_leftObjectsCount(0)
+FloatingObjects::FloatingObjects(const RenderBlockFlow& renderer)
+    : m_leftObjectsCount(0)
     , m_rightObjectsCount(0)
-    , m_horizontalWritingMode(horizontalWritingMode)
+    , m_horizontalWritingMode(renderer.isHorizontalWritingMode())
     , m_renderer(renderer)
 {
 }
 
-FloatingObjects::~FloatingObjects()
-{
-}
+FloatingObjects::~FloatingObjects() = default;
 
 void FloatingObjects::clearLineBoxTreePointers()
 {
     // Clear references to originating lines, since the lines are being deleted
     for (auto it = m_set.begin(), end = m_set.end(); it != end; ++it) {
-        ASSERT(!((*it)->originatingLine()) || &((*it)->originatingLine()->renderer()) == m_renderer);
-        (*it)->setOriginatingLine(0);
+        ASSERT(!((*it)->originatingLine()) || &((*it)->originatingLine()->renderer()) == &m_renderer);
+        (*it)->clearOriginatingLine();
     }
 }
 
 void FloatingObjects::clear()
 {
     m_set.clear();
-    m_placedFloatsTree.clear();
+    m_placedFloatsTree = nullptr;
     m_leftObjectsCount = 0;
     m_rightObjectsCount = 0;
 }
@@ -258,7 +280,7 @@ void FloatingObjects::moveAllToFloatInfoMap(RendererToFloatInfoMap& map)
         // FIXME: The only reason it is safe to move these out of the set is that
         // we are about to clear it. Otherwise it would break the hash table invariant.
         // A clean way to do this would be to add a takeAll function to HashSet.
-        map.add(&renderer, std::move(*it));
+        map.add(&renderer, WTFMove(*it));
     }
     clear();
 }
@@ -281,9 +303,11 @@ void FloatingObjects::decreaseObjectsCount(FloatingObject::Type type)
 
 FloatingObjectInterval FloatingObjects::intervalForFloatingObject(FloatingObject* floatingObject)
 {
+    // FIXME The endpoints of the floating object interval shouldn't need to be
+    // floored. See http://wkb.ug/125831 for more details.
     if (m_horizontalWritingMode)
-        return FloatingObjectInterval(floatingObject->frameRect().y(), floatingObject->frameRect().maxY(), floatingObject);
-    return FloatingObjectInterval(floatingObject->frameRect().x(), floatingObject->frameRect().maxX(), floatingObject);
+        return FloatingObjectInterval(floatingObject->frameRect().y().floor(), floatingObject->frameRect().maxY().floor(), floatingObject);
+    return FloatingObjectInterval(floatingObject->frameRect().x().floor(), floatingObject->frameRect().maxX().floor(), floatingObject);
 }
 
 void FloatingObjects::addPlacedObject(FloatingObject* floatingObject)
@@ -291,8 +315,8 @@ void FloatingObjects::addPlacedObject(FloatingObject* floatingObject)
     ASSERT(!floatingObject->isInPlacedTree());
 
     floatingObject->setIsPlaced(true);
-    if (m_placedFloatsTree.isInitialized())
-        m_placedFloatsTree.add(intervalForFloatingObject(floatingObject));
+    if (m_placedFloatsTree)
+        m_placedFloatsTree->add(intervalForFloatingObject(floatingObject));
 
 #ifndef NDEBUG
     floatingObject->setIsInPlacedTree(true);
@@ -303,8 +327,8 @@ void FloatingObjects::removePlacedObject(FloatingObject* floatingObject)
 {
     ASSERT(floatingObject->isPlaced() && floatingObject->isInPlacedTree());
 
-    if (m_placedFloatsTree.isInitialized()) {
-        bool removed = m_placedFloatsTree.remove(intervalForFloatingObject(floatingObject));
+    if (m_placedFloatsTree) {
+        bool removed = m_placedFloatsTree->remove(intervalForFloatingObject(floatingObject));
         ASSERT_UNUSED(removed, removed);
     }
 
@@ -319,7 +343,7 @@ FloatingObject* FloatingObjects::add(std::unique_ptr<FloatingObject> floatingObj
     increaseObjectsCount(floatingObject->type());
     if (floatingObject->isPlaced())
         addPlacedObject(floatingObject.get());
-    return m_set.add(std::move(floatingObject)).iterator->get();
+    return m_set.add(WTFMove(floatingObject)).iterator->get();
 }
 
 void FloatingObjects::remove(FloatingObject* floatingObject)
@@ -338,64 +362,30 @@ void FloatingObjects::remove(FloatingObject* floatingObject)
 
 void FloatingObjects::computePlacedFloatsTree()
 {
-    ASSERT(!m_placedFloatsTree.isInitialized());
+    ASSERT(!m_placedFloatsTree);
     if (m_set.isEmpty())
         return;
-    m_placedFloatsTree.initIfNeeded(m_renderer->view().intervalArena());
+
+    m_placedFloatsTree = std::make_unique<FloatingObjectTree>();
     for (auto it = m_set.begin(), end = m_set.end(); it != end; ++it) {
         FloatingObject* floatingObject = it->get();
         if (floatingObject->isPlaced())
-            m_placedFloatsTree.add(intervalForFloatingObject(floatingObject));
+            m_placedFloatsTree->add(intervalForFloatingObject(floatingObject));
     }
 }
 
-inline const FloatingObjectTree& FloatingObjects::placedFloatsTree()
+inline const FloatingObjectTree* FloatingObjects::placedFloatsTree()
 {
-    if (!m_placedFloatsTree.isInitialized())
+    if (!m_placedFloatsTree)
         computePlacedFloatsTree();
-    return m_placedFloatsTree;
-}
-
-#if ENABLE(CSS_SHAPES)
-static inline ShapeOutsideInfo* shapeInfoForFloat(const FloatingObject* floatingObject, const RenderBlockFlow* containingBlock, LayoutUnit lineTop, LayoutUnit lineBottom)
-{
-    if (floatingObject) {
-        if (ShapeOutsideInfo* shapeOutside = floatingObject->renderer().shapeOutsideInfo()) {
-            shapeOutside->updateDeltasForContainingBlockLine(containingBlock, floatingObject, lineTop, lineBottom - lineTop);
-            return shapeOutside;
-        }
-    }
-
-    return 0;
-}
-#endif
-
-template<>
-inline LayoutUnit ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::shapeOffset() const
-{
-#if ENABLE(CSS_SHAPES)
-    if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(m_outermostFloat, m_renderer, m_lineTop, m_lineBottom))
-        return m_offset + shapeOutside->rightMarginBoxDelta();
-#endif
-
-    return m_offset;
-}
-
-template<>
-inline LayoutUnit ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::shapeOffset() const
-{
-#if ENABLE(CSS_SHAPES)
-    if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(m_outermostFloat, m_renderer, m_lineTop, m_lineBottom))
-        return m_offset + shapeOutside->leftMarginBoxDelta();
-#endif
-
-    return m_offset;
+    return m_placedFloatsTree.get();
 }
 
 LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
 {
-    ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTop, logicalTop, fixedOffset);
-    placedFloatsTree().allOverlapsWithAdapter(adapter);
+    ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTop, logicalTop, fixedOffset);
+    if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree())
+        placedFloatsTree->allOverlapsWithAdapter(adapter);
 
     if (heightRemaining)
         *heightRemaining = adapter.heightRemaining();
@@ -405,35 +395,38 @@ LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixe
 
 LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
 {
-    ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTop, logicalTop, fixedOffset);
-    placedFloatsTree().allOverlapsWithAdapter(adapter);
+    ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTop, logicalTop, fixedOffset);
+    if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree())
+        placedFloatsTree->allOverlapsWithAdapter(adapter);
 
     if (heightRemaining)
         *heightRemaining = adapter.heightRemaining();
 
-    return min(fixedOffset, adapter.offset());
+    return std::min(fixedOffset, adapter.offset());
 }
 
 LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight)
 {
-    ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset);
-    placedFloatsTree().allOverlapsWithAdapter(adapter);
+    ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset);
+    if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree())
+        placedFloatsTree->allOverlapsWithAdapter(adapter);
 
-    return adapter.shapeOffset();
+    return adapter.offset();
 }
 
 LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight)
 {
-    ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset);
-    placedFloatsTree().allOverlapsWithAdapter(adapter);
+    ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset);
+    if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree())
+        placedFloatsTree->allOverlapsWithAdapter(adapter);
 
-    return min(fixedOffset, adapter.shapeOffset());
+    return std::min(fixedOffset, adapter.offset());
 }
 
 template<>
-inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject& floatingObject)
 {
-    LayoutUnit logicalRight = m_renderer->logicalRightForFloat(floatingObject);
+    LayoutUnit logicalRight = m_renderer.logicalRightForFloat(floatingObject);
     if (logicalRight > m_offset) {
         m_offset = logicalRight;
         return true;
@@ -442,9 +435,9 @@ inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::updateOffsetIf
 }
 
 template<>
-inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject& floatingObject)
 {
-    LayoutUnit logicalLeft = m_renderer->logicalLeftForFloat(floatingObject);
+    LayoutUnit logicalLeft = m_renderer.logicalLeftForFloat(floatingObject);
     if (logicalLeft < m_offset) {
         m_offset = logicalLeft;
         return true;
@@ -453,39 +446,63 @@ inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::updateOffsetI
 }
 
 template <FloatingObject::Type FloatTypeValue>
+LayoutUnit ComputeFloatOffsetForFloatLayoutAdapter<FloatTypeValue>::heightRemaining() const
+{
+    return this->m_outermostFloat ? this->m_renderer.logicalBottomForFloat(*this->m_outermostFloat) - this->m_lineTop : LayoutUnit::fromPixel(1);
+}
+
+template <FloatingObject::Type FloatTypeValue>
 inline void ComputeFloatOffsetAdapter<FloatTypeValue>::collectIfNeeded(const IntervalType& interval)
 {
-    const FloatingObject* floatingObject = interval.data();
-    if (floatingObject->type() != FloatTypeValue || !rangesIntersect(interval.low(), interval.high(), m_lineTop, m_lineBottom))
+    const auto& floatingObject = *interval.data();
+    if (floatingObject.type() != FloatTypeValue || !rangesIntersect(interval.low(), interval.high(), m_lineTop, m_lineBottom))
         return;
 
     // All the objects returned from the tree should be already placed.
-    ASSERT(floatingObject->isPlaced());
-    ASSERT(rangesIntersect(m_renderer->pixelSnappedLogicalTopForFloat(floatingObject), m_renderer->pixelSnappedLogicalBottomForFloat(floatingObject), m_lineTop, m_lineBottom));
+    ASSERT(floatingObject.isPlaced());
+    ASSERT(rangesIntersect(m_renderer.logicalTopForFloat(floatingObject), m_renderer.logicalBottomForFloat(floatingObject), m_lineTop, m_lineBottom));
 
     bool floatIsNewExtreme = updateOffsetIfNeeded(floatingObject);
     if (floatIsNewExtreme)
-        m_outermostFloat = floatingObject;
+        m_outermostFloat = &floatingObject;
 }
 
-template <FloatingObject::Type FloatTypeValue>
-LayoutUnit ComputeFloatOffsetAdapter<FloatTypeValue>::heightRemaining() const
+template<>
+inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject& floatingObject)
 {
-    return m_outermostFloat ? m_renderer->logicalBottomForFloat(m_outermostFloat) - m_lineTop : LayoutUnit(1);
-}
+    LayoutUnit logicalRight = m_renderer.logicalRightForFloat(floatingObject);
+    if (ShapeOutsideInfo* shapeOutside = floatingObject.renderer().shapeOutsideInfo()) {
+        ShapeOutsideDeltas shapeDeltas = shapeOutside->computeDeltasForContainingBlockLine(m_renderer, floatingObject, m_lineTop, m_lineBottom - m_lineTop);
+        if (!shapeDeltas.lineOverlapsShape())
+            return false;
 
-#ifndef NDEBUG
-// These helpers are only used by the PODIntervalTree for debugging purposes.
-String ValueToString<int>::string(const int value)
-{
-    return String::number(value);
+        logicalRight += shapeDeltas.rightMarginBoxDelta();
+    }
+    if (logicalRight > m_offset) {
+        m_offset = logicalRight;
+        return true;
+    }
+
+    return false;
 }
 
-String ValueToString<FloatingObject*>::string(const FloatingObject* floatingObject)
+template<>
+inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject& floatingObject)
 {
-    return String::format("%p (%ix%i %ix%i)", floatingObject, floatingObject->frameRect().x().toInt(), floatingObject->frameRect().y().toInt(), floatingObject->frameRect().maxX().toInt(), floatingObject->frameRect().maxY().toInt());
-}
-#endif
+    LayoutUnit logicalLeft = m_renderer.logicalLeftForFloat(floatingObject);
+    if (ShapeOutsideInfo* shapeOutside = floatingObject.renderer().shapeOutsideInfo()) {
+        ShapeOutsideDeltas shapeDeltas = shapeOutside->computeDeltasForContainingBlockLine(m_renderer, floatingObject, m_lineTop, m_lineBottom - m_lineTop);
+        if (!shapeDeltas.lineOverlapsShape())
+            return false;
 
+        logicalLeft += shapeDeltas.leftMarginBoxDelta();
+    }
+    if (logicalLeft < m_offset) {
+        m_offset = logicalLeft;
+        return true;
+    }
+
+    return false;
+}
 
 } // namespace WebCore