Chromium Code Reviews| Index: Source/core/layout/LayoutBlockFlow.cpp |
| diff --git a/Source/core/layout/LayoutBlockFlow.cpp b/Source/core/layout/LayoutBlockFlow.cpp |
| index d5aa6480168454a965083e47349e587897ca1998..f4f83857db8df299939152089f372e08d8e88f9e 100644 |
| --- a/Source/core/layout/LayoutBlockFlow.cpp |
| +++ b/Source/core/layout/LayoutBlockFlow.cpp |
| @@ -472,16 +472,23 @@ inline bool LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & |
| updateLogicalHeight(); |
| LayoutUnit newHeight = logicalHeight(); |
| - if (oldHeight > newHeight && !childrenInline()) { |
| + if (!childrenInline()) { |
| + LayoutBlockFlow* lowestBlock = nullptr; |
| + bool addedOverhangingFloats = false; |
| // One of our children's floats may have become an overhanging float for us. |
| for (LayoutObject* child = lastChild(); child; child = child->previousSibling()) { |
| + // TODO(robhogan): We should exclude blocks that create formatting contexts, not just out of flow or floating blocks. |
| if (child->isLayoutBlockFlow() && !child->isFloatingOrOutOfFlowPositioned()) { |
| LayoutBlockFlow* block = toLayoutBlockFlow(child); |
| - if (block->lowestFloatLogicalBottom() + block->logicalTop() <= newHeight) |
| + lowestBlock = block; |
| + if (oldHeight <= newHeight || block->lowestFloatLogicalBottom() + block->logicalTop() <= newHeight) |
| break; |
| addOverhangingFloats(block, false); |
| + addedOverhangingFloats = true; |
| } |
| } |
| + if (!addedOverhangingFloats) |
| + addLowestFloatFromChildren(lowestBlock); |
| } |
| bool heightChanged = (previousHeight != newHeight); |
| @@ -497,6 +504,26 @@ inline bool LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & |
| return true; |
| } |
| +void LayoutBlockFlow::addLowestFloatFromChildren(LayoutBlockFlow* block) |
| +{ |
| + // TODO(robhogan): Make createsNewFormattingContext an ASSERT. |
| + if (!block || !block->containsFloats() || block->createsNewFormattingContext()) |
| + return; |
| + |
| + FloatingObject* floatingObject = block->m_floatingObjects->lowestFloatingObject(); |
| + if (!floatingObject || containsFloat(floatingObject->layoutObject())) |
| + return; |
| + |
| + LayoutSize offset(-block->logicalLeft(), -block->logicalTop()); |
| + if (!isHorizontalWritingMode()) |
| + offset = offset.transposedSize(); |
| + |
| + if (!m_floatingObjects) |
| + createFloatingObjects(); |
| + FloatingObject* newFloatingObject = m_floatingObjects->add(floatingObject->copyToNewContainer(offset, false, true)); |
| + newFloatingObject->setIsLowestNonOverhangingFloatInChild(true); |
|
leviw_travelin_and_unemployed
2015/06/02 23:05:41
If new floats get added, it seems possible for the
rhogan
2015/06/03 20:30:55
m_floatingObjects gets cleared down at the start o
|
| +} |
| + |
| void LayoutBlockFlow::determineLogicalLeftPositionForChild(LayoutBox& child) |
| { |
| LayoutUnit startPosition = borderStart() + paddingStart(); |
| @@ -2583,7 +2610,7 @@ void LayoutBlockFlow::addOverhangingFloats(LayoutBlockFlow* child, bool makeChil |
| // behaves properly). We always want to propagate the desire to paint the float as |
| // far out as we can, to the outermost block that overlaps the float, stopping only |
| // if we hit a self-painting layer boundary. |
| - if (floatingObject->layoutObject()->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer()) { |
| + if (floatingObject->layoutObject()->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer() && !floatingObject->isLowestNonOverhangingFloatInChild()) { |
| floatingObject->setShouldPaint(false); |
| shouldPaint = true; |
| } |
| @@ -2594,7 +2621,7 @@ void LayoutBlockFlow::addOverhangingFloats(LayoutBlockFlow* child, bool makeChil |
| m_floatingObjects->add(floatingObject->copyToNewContainer(offset, shouldPaint, true)); |
| } |
| } else { |
| - if (makeChildPaintOtherFloats && !floatingObject->shouldPaint() && !floatingObject->layoutObject()->hasSelfPaintingLayer() |
| + if (makeChildPaintOtherFloats && !floatingObject->shouldPaint() && !floatingObject->layoutObject()->hasSelfPaintingLayer() && !floatingObject->isLowestNonOverhangingFloatInChild() |
| && floatingObject->layoutObject()->isDescendantOf(child) && floatingObject->layoutObject()->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) { |
| // The float is not overhanging from this block, so if it is a descendant of the child, the child should |
| // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing |