https://bugs.webkit.org/show_bug.cgi?id=47021
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 2 Oct 2010 00:13:00 +0000 (00:13 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 2 Oct 2010 00:13:00 +0000 (00:13 +0000)
Reviewed by Dan Bernstein.

Patch the floatBottom function and its friends.  Rename them and consolidate them to be block-flow-aware.

Nothing testable yet, since most of the float code is still unpatched.

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::layoutBlock):
(WebCore::RenderBlock::layoutBlockChildren):
(WebCore::RenderBlock::layoutBlockChild):
(WebCore::RenderBlock::positionNewFloats):
(WebCore::RenderBlock::newLine):
(WebCore::RenderBlock::nextFloatLogicalBottomBelow):
(WebCore::RenderBlock::lowestFloatLogicalBottom):
(WebCore::RenderBlock::clearFloats):
(WebCore::RenderBlock::addOverhangingFloats):
(WebCore::RenderBlock::getClearDelta):
* rendering/RenderBlock.h:
(WebCore::RenderBlock::logicalBottomForFloat):
(WebCore::RenderBlock::hasOverhangingFloats):
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlock::fitBelowFloats):

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

WebCore/ChangeLog
WebCore/rendering/RenderBlock.cpp
WebCore/rendering/RenderBlock.h
WebCore/rendering/RenderBlockLineLayout.cpp

index 8f5c497..eec89fa 100644 (file)
@@ -1,3 +1,30 @@
+2010-10-01  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        https://bugs.webkit.org/show_bug.cgi?id=47021
+        
+        Patch the floatBottom function and its friends.  Rename them and consolidate them to be block-flow-aware.
+
+        Nothing testable yet, since most of the float code is still unpatched.
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::layoutBlock):
+        (WebCore::RenderBlock::layoutBlockChildren):
+        (WebCore::RenderBlock::layoutBlockChild):
+        (WebCore::RenderBlock::positionNewFloats):
+        (WebCore::RenderBlock::newLine):
+        (WebCore::RenderBlock::nextFloatLogicalBottomBelow):
+        (WebCore::RenderBlock::lowestFloatLogicalBottom):
+        (WebCore::RenderBlock::clearFloats):
+        (WebCore::RenderBlock::addOverhangingFloats):
+        (WebCore::RenderBlock::getClearDelta):
+        * rendering/RenderBlock.h:
+        (WebCore::RenderBlock::logicalBottomForFloat):
+        (WebCore::RenderBlock::hasOverhangingFloats):
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlock::fitBelowFloats):
+
 2010-10-01  Anders Carlsson  <andersca@apple.com>
 
         Fix typo.
index 2907efe..f49c598 100644 (file)
@@ -1198,18 +1198,18 @@ void RenderBlock::layoutBlock(bool relayoutChildren, int pageHeight)
 
     int repaintTop = 0;
     int repaintBottom = 0;
-    int maxFloatBottom = 0;
+    int maxFloatLogicalBottom = 0;
     if (!firstChild() && !isAnonymousBlock())
         setChildrenInline(true);
     if (childrenInline())
         layoutInlineChildren(relayoutChildren, repaintTop, repaintBottom);
     else
-        layoutBlockChildren(relayoutChildren, maxFloatBottom);
+        layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom);
 
     // Expand our intrinsic height to encompass floats.
     int toAdd = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
-    if (floatBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
-        setLogicalHeight(floatBottom() + toAdd);
+    if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
+        setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
     
     if (layoutColumns(hasSpecifiedPageHeight, pageHeight, statePusher))
         return;
@@ -1219,12 +1219,12 @@ void RenderBlock::layoutBlock(bool relayoutChildren, int pageHeight)
     computeLogicalHeight();
     int newHeight = logicalHeight();
     if (oldHeight != newHeight) {
-        if (oldHeight > newHeight && maxFloatBottom > newHeight && !childrenInline()) {
+        if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
             // One of our children's floats may have become an overhanging float for us. We need to look for it.
             for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
                 if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
                     RenderBlock* block = toRenderBlock(child);
-                    if (block->floatBottom() + block->logicalTop() > newHeight)
+                    if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
                         addOverhangingFloats(block, -block->x(), -block->y(), false);
                 }
             }
@@ -1739,7 +1739,7 @@ void RenderBlock::setLogicalTopForChild(RenderBox* child, int logicalTop)
     }
 }
 
-void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom)
+void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatLogicalBottom)
 {
     if (gPercentHeightDescendantsMap) {
         if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
@@ -1773,8 +1773,8 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom
     // https://bugs.webkit.org/show_bug.cgi?id=46785
     RenderObject* legend = layoutLegend(relayoutChildren);
 
-    int previousFloatBottom = 0;
-    maxFloatBottom = 0;
+    int previousFloatLogicalBottom = 0;
+    maxFloatLogicalBottom = 0;
 
     RenderBox* next = firstChildBox();
 
@@ -1801,7 +1801,7 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom
             continue;
 
         // Lay out the child.
-        layoutBlockChild(child, marginInfo, previousFloatBottom, maxFloatBottom);
+        layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
     }
     
     // Now do the handling of the bottom of the block, adding in our bottom border/padding and
@@ -1809,7 +1809,7 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom
     handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
 }
 
-void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatBottom, int& maxFloatBottom)
+void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatLogicalBottom, int& maxFloatLogicalBottom)
 {
     int oldPosMarginBefore = maxPositiveMarginBefore();
     int oldNegMarginBefore = maxNegativeMarginBefore();
@@ -1845,7 +1845,7 @@ void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int
     else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
         // If an element might be affected by the presence of floats, then always mark it for
         // layout.
-        int fb = max(previousFloatBottom, floatBottom());
+        int fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom());
         if (fb > logicalTopEstimate)
             markDescendantsWithFloats = true;
     }
@@ -1854,7 +1854,7 @@ void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int
         if (markDescendantsWithFloats)
             childRenderBlock->markAllDescendantsWithFloatsForLayout();
         if (!child->isBlockFlowRoot())
-            previousFloatBottom = max(previousFloatBottom, oldLogicalTop + childRenderBlock->floatBottom());
+            previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottom());
     }
 
     bool paginated = view()->layoutState()->isPaginated();
@@ -1950,7 +1950,7 @@ void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int
     // If the child has overhanging floats that intrude into following siblings (or possibly out
     // of this block), then the parent gets notified of the floats now.
     if (childRenderBlock && childRenderBlock->containsFloats())
-        maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout));
+        maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout));
 
     IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
     if (childOffset.width() || childOffset.height()) {
@@ -3029,9 +3029,9 @@ bool RenderBlock::positionNewFloats()
         IntRect oldRect(o->x(), o->y() , o->width(), o->height());
 
         if (o->style()->clear() & CLEFT)
-            y = max(leftBottom(), y);
+            y = max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), y);
         if (o->style()->clear() & CRIGHT)
-            y = max(rightBottom(), y);
+            y = max(lowestFloatLogicalBottom(FloatingObject::FloatRight), y);
 
         if (o->style()->floating() == FLEFT) {
             int heightRemainingLeft = 1;
@@ -3138,13 +3138,13 @@ void RenderBlock::newLine(EClear clear)
     switch (clear)
     {
         case CLEFT:
-            newY = leftBottom();
+            newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
             break;
         case CRIGHT:
-            newY = rightBottom();
+            newY = lowestFloatLogicalBottom(FloatingObject::FloatRight);
             break;
         case CBOTH:
-            newY = floatBottom();
+            newY = lowestFloatLogicalBottom();
         default:
             break;
     }
@@ -3276,7 +3276,7 @@ RenderBlock::availableLogicalWidthForLine(int position, bool firstLine) const
     return (result < 0) ? 0 : result;
 }
 
-int RenderBlock::nextFloatBottomBelow(int height) const
+int RenderBlock::nextFloatLogicalBottomBelow(int logicalHeight) const
 {
     if (!m_floatingObjects)
         return 0;
@@ -3285,24 +3285,26 @@ int RenderBlock::nextFloatBottomBelow(int height) const
     FloatingObject* r;
     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
     for ( ; (r = it.current()); ++it) {
-        if (r->bottom() > height)
-            bottom = min(r->bottom(), bottom);
+        int floatBottom = logicalBottomForFloat(r);
+        if (floatBottom > logicalHeight)
+            bottom = min(floatBottom, bottom);
     }
 
     return bottom == INT_MAX ? 0 : bottom;
 }
 
-int
-RenderBlock::floatBottom() const
+int RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
 {
-    if (!m_floatingObjects) return 0;
-    int bottom = 0;
+    if (!m_floatingObjects)
+        return 0;
+    int lowestFloatBottom = 0;
     FloatingObject* r;
     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
-    for ( ; (r = it.current()); ++it )
-        if (r->bottom() > bottom)
-            bottom = r->bottom();
-    return bottom;
+    for ( ; (r = it.current()); ++it) {
+        if (r->type() & floatType)
+            lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r));
+    }
+    return lowestFloatBottom;
 }
 
 int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) const
@@ -3583,32 +3585,6 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
     return left;
 }
 
-int RenderBlock::leftBottom()
-{
-    if (!m_floatingObjects) return 0;
-    int bottom = 0;
-    FloatingObject* r;
-    DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
-    for ( ; (r = it.current()); ++it)
-        if (r->bottom() > bottom && r->type() == FloatingObject::FloatLeft)
-            bottom = r->bottom();
-
-    return bottom;
-}
-
-int RenderBlock::rightBottom()
-{
-    if (!m_floatingObjects) return 0;
-    int bottom = 0;
-    FloatingObject* r;
-    DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
-    for ( ; (r = it.current()); ++it)
-        if (r->bottom() > bottom && r->type() == FloatingObject::FloatRight)
-            bottom = r->bottom();
-
-    return bottom;
-}
-
 void RenderBlock::markLinesDirtyInVerticalRange(int top, int bottom, RootInlineBox* highest)
 {
     if (top >= bottom)
@@ -3685,7 +3661,7 @@ void RenderBlock::clearFloats()
         return;
     
     RenderBlock* block = toRenderBlock(prev);
-    if (block->m_floatingObjects && block->floatBottom() > offset)
+    if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > offset)
         addIntrudingFloats(block, xoffset, offset);
 
     if (childrenInline()) {
@@ -3732,14 +3708,14 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff, bo
     if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns() || child->isBlockFlowRoot())
         return 0;
 
-    int lowestFloatBottom = 0;
+    int lowestFloatLogicalBottom = 0;
 
     // Floats that will remain the child's responsibility to paint should factor into its
     // overflow.
     DeprecatedPtrListIterator<FloatingObject> it(*child->m_floatingObjects);
     for (FloatingObject* r; (r = it.current()); ++it) {
         int bottom = child->y() + r->bottom();
-        lowestFloatBottom = max(lowestFloatBottom, bottom);
+        lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, bottom);
 
         if (bottom > height()) {
             // If the object is not in the list, we add it now.
@@ -3775,7 +3751,7 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff, bo
         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer())
             child->addOverflowFromChild(r->m_renderer, IntSize(r->left() + r->m_renderer->marginLeft(), r->top() + r->m_renderer->marginTop()));
     }
-    return lowestFloatBottom;
+    return lowestFloatLogicalBottom;
 }
 
 void RenderBlock::addIntrudingFloats(RenderBlock* prev, int xoff, int yoff)
@@ -3911,13 +3887,13 @@ int RenderBlock::getClearDelta(RenderBox* child, int yPos)
         case CNONE:
             break;
         case CLEFT:
-            bottom = leftBottom();
+            bottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
             break;
         case CRIGHT:
-            bottom = rightBottom();
+            bottom = lowestFloatLogicalBottom(FloatingObject::FloatRight);
             break;
         case CBOTH:
-            bottom = floatBottom();
+            bottom = lowestFloatLogicalBottom();
             break;
     }
 
@@ -3945,7 +3921,7 @@ int RenderBlock::getClearDelta(RenderBox* child, int yPos)
             if (childWidthAtY <= widthAtY)
                 return y - yPos;
 
-            y = nextFloatBottomBelow(y);
+            y = nextFloatLogicalBottomBelow(y);
             ASSERT(y >= yPos);
             if (y < yPos)
                 break;
index d58c48a..6430218 100644 (file)
@@ -185,7 +185,7 @@ public:
     void setMarginAfterForChild(RenderBox* child, int);
     int collapsedMarginBeforeForChild(RenderBox* child) const;
     int collapsedMarginAfterForChild(RenderBox* child) const;
-    
+
     class MarginValues {
     public:
         MarginValues(int beforePos, int beforeNeg, int afterPos, int afterNeg)
@@ -331,7 +331,7 @@ private:
 
     virtual void repaintOverhangingFloats(bool paintAllDescendants);
 
-    void layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom);
+    void layoutBlockChildren(bool relayoutChildren, int& maxFloatLogicalBottom);
     void layoutInlineChildren(bool relayoutChildren, int& repaintTop, int& repaintBottom);
 
     virtual void positionListMarker() { }
@@ -359,11 +359,9 @@ private:
     };
 
     struct FloatingObject : Noncopyable {
-        enum Type {
-            FloatLeft,
-            FloatRight
-        };
-
+        // Note that Type uses bits so you can use FloatBoth as a mask to query for both left and right.
+        enum Type { FloatLeft = 1, FloatRight = 2, FloatBoth = 3 };
+    
         FloatingObject(Type type, const IntRect& frameRect = IntRect())
             : m_renderer(0)
             , m_frameRect(frameRect)
@@ -394,11 +392,13 @@ private:
         RenderBox* m_renderer;
         IntRect m_frameRect;
         int m_paginationStrut;
-        unsigned m_type : 1; // Type (left or right aligned)
+        unsigned m_type : 2; // Type (left or right aligned)
         bool m_shouldPaint : 1;
         bool m_isDescendant : 1;
     };
 
+    int logicalBottomForFloat(FloatingObject* child) const { return style()->isVerticalBlockFlow() ? child->bottom() : child->right(); }
+    
     // The following functions' implementations are in RenderBlockLineLayout.cpp.
     RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
                                           InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats,
@@ -451,15 +451,13 @@ private:
 
     virtual bool avoidsFloats() const;
 
-    bool hasOverhangingFloats() { return parent() && !hasColumns() && floatBottom() > height(); }
+    bool hasOverhangingFloats() { return parent() && !hasColumns() && lowestFloatLogicalBottom() > logicalHeight(); }
     void addIntrudingFloats(RenderBlock* prev, int xoffset, int yoffset);
     int addOverhangingFloats(RenderBlock* child, int xoffset, int yoffset, bool makeChildPaintOtherFloats);
 
-    int nextFloatBottomBelow(int) const;
-    int floatBottom() const;
-    inline int leftBottom();
-    inline int rightBottom();
-
+    int lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatBoth) const;
+    int nextFloatLogicalBottomBelow(int) const;
+    
     virtual bool hitTestColumns(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
     virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
     bool hitTestFloats(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty);
@@ -602,7 +600,7 @@ private:
         int margin() const { return m_positiveMargin - m_negativeMargin; }
     };
 
-    void layoutBlockChild(RenderBox* child, MarginInfo&, int& previousFloatBottom, int& maxFloatBottom);
+    void layoutBlockChild(RenderBox* child, MarginInfo&, int& previousFloatLogicalBottom, int& maxFloatLogicalBottom);
     void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
     void adjustFloatingBlock(const MarginInfo&);
     bool handleSpecialChild(RenderBox* child, const MarginInfo&);
index ff4e62f..e6b5984 100644 (file)
@@ -1330,22 +1330,22 @@ void RenderBlock::fitBelowFloats(int widthToFit, bool firstLine, int& availableW
 {
     ASSERT(widthToFit > availableWidth);
 
-    int floatBottom;
-    int lastFloatBottom = height();
+    int floatLogicalBottom;
+    int lastFloatLogicalBottom = height();
     int newLineWidth = availableWidth;
     while (true) {
-        floatBottom = nextFloatBottomBelow(lastFloatBottom);
-        if (!floatBottom)
+        floatLogicalBottom = nextFloatLogicalBottomBelow(lastFloatLogicalBottom);
+        if (!floatLogicalBottom)
             break;
 
-        newLineWidth = availableLogicalWidthForLine(floatBottom, firstLine);
-        lastFloatBottom = floatBottom;
+        newLineWidth = availableLogicalWidthForLine(floatLogicalBottom, firstLine);
+        lastFloatLogicalBottom = floatLogicalBottom;
         if (newLineWidth >= widthToFit)
             break;
     }
 
     if (newLineWidth > availableWidth) {
-        setLogicalHeight(lastFloatBottom);
+        setLogicalHeight(lastFloatLogicalBottom);
         availableWidth = newLineWidth;
     }
 }