RenderBlockFlow::nextFloatLogicalBottomBelow should not use ShapeOutsideFloatOffsetMode
authorbjonesbe@adobe.com <bjonesbe@adobe.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Nov 2013 22:01:33 +0000 (22:01 +0000)
committerbjonesbe@adobe.com <bjonesbe@adobe.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Nov 2013 22:01:33 +0000 (22:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=123931

Reviewed by Sam Weinig.

Rewrite nextFloatLogicalBottomBelow to use the placed floats tree for
the search and to not need ShapeOutsideFloatOffsetMode anymore. This
moves almost all of the logic into FloatingObjects, making a small
reduction in the amount that RenderBlockFlow needs to know about the
implementation of FloatingObjects.

In addition, change ComputeFloatOffsetAdapter to take in LayoutUnits
and roundToInt itself so that all of it's callers can be simplified.

No new tests, no new behavior.

* rendering/FloatingObjects.cpp:
(WebCore::rangesIntersect):
(WebCore::ComputeFloatOffsetAdapter::ComputeFloatOffsetAdapter):
(WebCore::FindNextFloatLogicalBottomAdapter::FindNextFloatLogicalBottomAdapter):
(WebCore::FindNextFloatLogicalBottomAdapter::lowValue):
(WebCore::FindNextFloatLogicalBottomAdapter::highValue):
(WebCore::FindNextFloatLogicalBottomAdapter::nextLogicalBottom):
(WebCore::FindNextFloatLogicalBottomAdapter::nextShapeLogicalBottom):
(WebCore::FindNextFloatLogicalBottomAdapter::collectIfNeeded):
(WebCore::FloatingObjects::findNextFloatLogicalBottomBelow):
(WebCore::FloatingObjects::findNextFloatLogicalBottomBelowForBlock):
(WebCore::FloatingObjects::logicalLeftOffsetForPositioningFloat):
(WebCore::FloatingObjects::logicalRightOffsetForPositioningFloat):
(WebCore::FloatingObjects::logicalLeftOffset):
(WebCore::FloatingObjects::logicalRightOffset):
* rendering/FloatingObjects.h:
* rendering/LineWidth.cpp:
(WebCore::LineWidth::fitBelowFloats):
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::nextFloatLogicalBottomBelow):
(WebCore::RenderBlockFlow::nextFloatLogicalBottomBelowForBlock):
(WebCore::RenderBlockFlow::getClearDelta):
* rendering/RenderBlockFlow.h:

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

Source/WebCore/ChangeLog
Source/WebCore/rendering/FloatingObjects.cpp
Source/WebCore/rendering/FloatingObjects.h
Source/WebCore/rendering/LineWidth.cpp
Source/WebCore/rendering/RenderBlockFlow.cpp
Source/WebCore/rendering/RenderBlockFlow.h

index 1001227..5e420cc 100644 (file)
@@ -1,3 +1,45 @@
+2013-11-08  Bem Jones-Bey  <bjonesbe@adobe.com>
+
+        RenderBlockFlow::nextFloatLogicalBottomBelow should not use ShapeOutsideFloatOffsetMode
+        https://bugs.webkit.org/show_bug.cgi?id=123931
+
+        Reviewed by Sam Weinig.
+
+        Rewrite nextFloatLogicalBottomBelow to use the placed floats tree for
+        the search and to not need ShapeOutsideFloatOffsetMode anymore. This
+        moves almost all of the logic into FloatingObjects, making a small
+        reduction in the amount that RenderBlockFlow needs to know about the
+        implementation of FloatingObjects.
+
+        In addition, change ComputeFloatOffsetAdapter to take in LayoutUnits
+        and roundToInt itself so that all of it's callers can be simplified.
+
+        No new tests, no new behavior.
+
+        * rendering/FloatingObjects.cpp:
+        (WebCore::rangesIntersect):
+        (WebCore::ComputeFloatOffsetAdapter::ComputeFloatOffsetAdapter):
+        (WebCore::FindNextFloatLogicalBottomAdapter::FindNextFloatLogicalBottomAdapter):
+        (WebCore::FindNextFloatLogicalBottomAdapter::lowValue):
+        (WebCore::FindNextFloatLogicalBottomAdapter::highValue):
+        (WebCore::FindNextFloatLogicalBottomAdapter::nextLogicalBottom):
+        (WebCore::FindNextFloatLogicalBottomAdapter::nextShapeLogicalBottom):
+        (WebCore::FindNextFloatLogicalBottomAdapter::collectIfNeeded):
+        (WebCore::FloatingObjects::findNextFloatLogicalBottomBelow):
+        (WebCore::FloatingObjects::findNextFloatLogicalBottomBelowForBlock):
+        (WebCore::FloatingObjects::logicalLeftOffsetForPositioningFloat):
+        (WebCore::FloatingObjects::logicalRightOffsetForPositioningFloat):
+        (WebCore::FloatingObjects::logicalLeftOffset):
+        (WebCore::FloatingObjects::logicalRightOffset):
+        * rendering/FloatingObjects.h:
+        * rendering/LineWidth.cpp:
+        (WebCore::LineWidth::fitBelowFloats):
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::nextFloatLogicalBottomBelow):
+        (WebCore::RenderBlockFlow::nextFloatLogicalBottomBelowForBlock):
+        (WebCore::RenderBlockFlow::getClearDelta):
+        * rendering/RenderBlockFlow.h:
+
 2013-11-08  Alexey Proskuryakov  <ap@apple.com>
 
         https://bugs.webkit.org/show_bug.cgi?id=124064
index a7a7907..4a04ade 100644 (file)
@@ -100,15 +100,35 @@ std::unique_ptr<FloatingObject> FloatingObject::unsafeClone() const
     return cloneObject;
 }
 
+inline static bool rangesIntersect(int floatTop, int floatBottom, int objectTop, int objectBottom)
+{
+    if (objectTop >= floatBottom || objectBottom < floatTop)
+        return false;
+
+    // The top of the object overlaps the float
+    if (objectTop >= floatTop)
+        return true;
+
+    // The object encloses the float
+    if (objectTop < floatTop && objectBottom > floatBottom)
+        return true;
+
+    // The bottom of the object overlaps the float
+    if (objectBottom > objectTop && objectBottom > floatTop && objectBottom <= floatBottom)
+        return true;
+
+    return false;
+}
+
 template <FloatingObject::Type FloatTypeValue>
 class ComputeFloatOffsetAdapter {
 public:
     typedef FloatingObjectInterval IntervalType;
 
-    ComputeFloatOffsetAdapter(const RenderBlockFlow* renderer, int lineTop, int lineBottom, LayoutUnit offset)
+    ComputeFloatOffsetAdapter(const RenderBlockFlow* renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
         : m_renderer(renderer)
-        , m_lineTop(lineTop)
-        , m_lineBottom(lineBottom)
+        , m_lineTop(roundToInt(lineTop))
+        , m_lineBottom(roundToInt(lineBottom))
         , m_offset(offset)
         , m_outermostFloat(0)
     {
@@ -132,6 +152,75 @@ private:
     const FloatingObject* m_outermostFloat;
 };
 
+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())
+    {
+    }
+
+    int lowValue() const { return m_belowLogicalHeight; }
+    int highValue() const { return m_aboveLogicalHeight; }
+    void collectIfNeeded(const IntervalType&);
+
+    LayoutUnit nextLogicalBottom() { return m_nextLogicalBottom == LayoutUnit::max() ? LayoutUnit() : m_nextLogicalBottom; }
+    LayoutUnit nextShapeLogicalBottom() { return m_nextShapeLogicalBottom == LayoutUnit::max() ? nextLogicalBottom() : m_nextShapeLogicalBottom; }
+
+private:
+    const RenderBlockFlow& m_renderer;
+    int m_belowLogicalHeight;
+    int m_aboveLogicalHeight;
+    LayoutUnit m_nextLogicalBottom;
+    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))
+        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));
+
+    LayoutUnit floatBottom = m_renderer.logicalBottomForFloat(floatingObject);
+    if (m_nextLogicalBottom < 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();
+        // Use the shapeBottom unless it extends outside of the margin box, in which case it is clipped.
+        m_nextShapeLogicalBottom = min(shapeBottom, floatBottom);
+    } else
+        m_nextShapeLogicalBottom = floatBottom;
+#endif
+    m_nextLogicalBottom = floatBottom;
+}
+
+LayoutUnit FloatingObjects::findNextFloatLogicalBottomBelow(LayoutUnit logicalHeight)
+{
+    FindNextFloatLogicalBottomAdapter adapter(*m_renderer, logicalHeight);
+    placedFloatsTree().allOverlapsWithAdapter(adapter);
+
+    return adapter.nextShapeLogicalBottom();
+}
+
+LayoutUnit FloatingObjects::findNextFloatLogicalBottomBelowForBlock(LayoutUnit logicalHeight)
+{
+    FindNextFloatLogicalBottomAdapter adapter(*m_renderer, logicalHeight);
+    placedFloatsTree().allOverlapsWithAdapter(adapter);
+
+    return adapter.nextLogicalBottom();
+}
+
 FloatingObjects::FloatingObjects(const RenderBlockFlow* renderer, bool horizontalWritingMode)
     : m_placedFloatsTree(UninitializedTree)
     , m_leftObjectsCount(0)
@@ -305,8 +394,7 @@ inline LayoutUnit ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::shapeOf
 
 LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
 {
-    int logicalTopAsInt = roundToInt(logicalTop);
-    ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
+    ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTop, logicalTop, fixedOffset);
     placedFloatsTree().allOverlapsWithAdapter(adapter);
 
     if (heightRemaining)
@@ -317,8 +405,7 @@ LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixe
 
 LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
 {
-    int logicalTopAsInt = roundToInt(logicalTop);
-    ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
+    ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTop, logicalTop, fixedOffset);
     placedFloatsTree().allOverlapsWithAdapter(adapter);
 
     if (heightRemaining)
@@ -329,7 +416,7 @@ LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fix
 
 LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight)
 {
-    ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset);
+    ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset);
     placedFloatsTree().allOverlapsWithAdapter(adapter);
 
     return adapter.shapeOffset();
@@ -337,32 +424,12 @@ LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit
 
 LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight)
 {
-    ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset);
+    ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset);
     placedFloatsTree().allOverlapsWithAdapter(adapter);
 
     return min(fixedOffset, adapter.shapeOffset());
 }
 
-inline static bool rangesIntersect(int floatTop, int floatBottom, int objectTop, int objectBottom)
-{
-    if (objectTop >= floatBottom || objectBottom < floatTop)
-        return false;
-
-    // The top of the object overlaps the float
-    if (objectTop >= floatTop)
-        return true;
-
-    // The object encloses the float
-    if (objectTop < floatTop && objectBottom > floatBottom)
-        return true;
-
-    // The bottom of the object overlaps the float
-    if (objectBottom > objectTop && objectBottom > floatTop && objectBottom <= floatBottom)
-        return true;
-
-    return false;
-}
-
 template<>
 inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
 {
index 47ec7bc..0b475cf 100644 (file)
@@ -33,9 +33,6 @@ namespace WebCore {
 class RenderBlockFlow;
 class RenderBox;
 
-// FIXME this should be removed once RenderBlockFlow::nextFloatLogicalBottomBelow doesn't need it anymore. (Bug 123931)
-enum ShapeOutsideFloatOffsetMode { ShapeOutsideFloatShapeOffset, ShapeOutsideFloatMarginBoxOffset };
-
 class FloatingObject {
     WTF_MAKE_NONCOPYABLE(FloatingObject); WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -149,6 +146,9 @@ public:
     LayoutUnit logicalLeftOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit* heightRemaining);
     LayoutUnit logicalRightOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit* heightRemaining);
 
+    LayoutUnit findNextFloatLogicalBottomBelow(LayoutUnit logicalHeight);
+    LayoutUnit findNextFloatLogicalBottomBelowForBlock(LayoutUnit logicalHeight);
+
 private:
     void computePlacedFloatsTree();
     const FloatingObjectTree& placedFloatsTree();
index 4f488a9..5418a40 100644 (file)
@@ -181,7 +181,7 @@ void LineWidth::fitBelowFloats()
     float newLineLeft = m_left;
     float newLineRight = m_right;
     while (true) {
-        floatLogicalBottom = m_block.nextFloatLogicalBottomBelow(lastFloatLogicalBottom, ShapeOutsideFloatShapeOffset);
+        floatLogicalBottom = m_block.nextFloatLogicalBottomBelow(lastFloatLogicalBottom);
         if (floatLogicalBottom <= lastFloatLogicalBottom)
             break;
 
index 9dc4e85..12cdb95 100644 (file)
@@ -2276,31 +2276,20 @@ LayoutUnit RenderBlockFlow::logicalRightFloatOffsetForLine(LayoutUnit logicalTop
     return fixedOffset;
 }
 
-LayoutUnit RenderBlockFlow::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode offsetMode) const
+LayoutUnit RenderBlockFlow::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight) const
 {
     if (!m_floatingObjects)
         return logicalHeight;
 
-    LayoutUnit bottom = LayoutUnit::max();
-    const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
-    auto end = floatingObjectSet.end();
-    for (auto it = floatingObjectSet.begin(); it != end; ++it) {
-        FloatingObject* floatingObject = it->get();
-        LayoutUnit floatBottom = logicalBottomForFloat(floatingObject);
-#if ENABLE(CSS_SHAPES)
-        ShapeOutsideInfo* shapeOutside = floatingObject->renderer().shapeOutsideInfo();
-        if (offsetMode == ShapeOutsideFloatShapeOffset && shapeOutside) {
-            LayoutUnit shapeBottom = logicalTopForFloat(floatingObject) + marginBeforeForChild(floatingObject->renderer()) + shapeOutside->shapeLogicalBottom();
-            // Use the shapeBottom unless it extends outside of the margin box, in which case it is clipped.
-            if (shapeBottom < floatBottom)
-                floatBottom = shapeBottom;
-        }
-#endif
-        if (floatBottom > logicalHeight)
-            bottom = min(floatBottom, bottom);
-    }
+    return m_floatingObjects->findNextFloatLogicalBottomBelow(logicalHeight);
+}
+
+LayoutUnit RenderBlockFlow::nextFloatLogicalBottomBelowForBlock(LayoutUnit logicalHeight) const
+{
+    if (!m_floatingObjects)
+        return logicalHeight;
 
-    return bottom == LayoutUnit::max() ? LayoutUnit() : bottom;
+    return m_floatingObjects->findNextFloatLogicalBottomBelowForBlock(logicalHeight);
 }
 
 LayoutUnit RenderBlockFlow::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
@@ -2552,7 +2541,7 @@ LayoutUnit RenderBlockFlow::getClearDelta(RenderBox& child, LayoutUnit logicalTo
                 return newLogicalTop - logicalTop;
             }
 
-            newLogicalTop = nextFloatLogicalBottomBelow(newLogicalTop);
+            newLogicalTop = nextFloatLogicalBottomBelowForBlock(newLogicalTop);
             ASSERT(newLogicalTop >= logicalTop);
             if (newLogicalTop < logicalTop)
                 break;
index e711dc0..012fc2c 100644 (file)
@@ -423,7 +423,8 @@ private:
     LayoutUnit logicalLeftOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
 
     LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const; 
-    LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit, ShapeOutsideFloatOffsetMode = ShapeOutsideFloatMarginBoxOffset) const;
+    LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit) const;
+    LayoutUnit nextFloatLogicalBottomBelowForBlock(LayoutUnit) const;
     
     LayoutUnit addOverhangingFloats(RenderBlockFlow& child, bool makeChildPaintOtherFloats);
     bool hasOverhangingFloat(RenderBox&);