Chromium Code Reviews| Index: Source/core/rendering/RenderLayer.cpp | 
| diff --git a/Source/core/rendering/RenderLayer.cpp b/Source/core/rendering/RenderLayer.cpp | 
| index 719dcefebe6bcf23d038fe433ca6d52844b70ae0..791e5316e1ddbe1c321a6401d85b7a8781560a7f 100644 | 
| --- a/Source/core/rendering/RenderLayer.cpp | 
| +++ b/Source/core/rendering/RenderLayer.cpp | 
| @@ -415,6 +415,38 @@ static bool checkContainingBlockChainForPagination(RenderLayerModelObject* rende | 
| return true; | 
| } | 
| +// Convert a bounding box from flow thread coordinates, relative to |layer|, to visual coordinates, relative to |ancestorLayer|. | 
| +static void convertFromFlowThreadToVisualBoundingBoxInAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutRect& rect) | 
| +{ | 
| + RenderLayer* paginationLayer = layer->enclosingPaginationLayer(); | 
| + ASSERT(paginationLayer); | 
| + RenderFlowThread* flowThread = toRenderFlowThread(paginationLayer->renderer()); | 
| + LayoutPoint offsetWithinPaginationLayer; | 
| + layer->convertToLayerCoords(paginationLayer, offsetWithinPaginationLayer); | 
| + | 
| + // First make the flow thread rectangle relative to the flow thread, not to |layer|. | 
| + rect.moveBy(offsetWithinPaginationLayer); | 
| + | 
| + // Then make the rectangle visual, relative to the fragmentation context. Split our box up into | 
| + // the actual fragment boxes that render in the columns/pages and unite those together to get | 
| + // our true bounding box. | 
| + rect = flowThread->fragmentsBoundingBox(rect); | 
| + | 
| + // Finally, make the visual rectangle relative to |ancestorLayer|. | 
| + // FIXME: nested fragmentation contexts. For now just give up if there are different pagination layers involved. | 
| + if (!ancestorLayer->enclosingPaginationLayer() || ancestorLayer->enclosingPaginationLayer() != paginationLayer) { | 
| + // The easy case. The ancestor layer is not within the pagination layer. | 
| + paginationLayer->convertToLayerCoords(ancestorLayer, rect); | 
| + return; | 
| + } | 
| + // Both this layer and the ancestor layer are inside the pagination layer, so we need to do some | 
| + // extra work to find the visual distance from the ancestor. | 
| 
 
rune
2014/10/13 09:35:02
I think something like this is clearer:
// The an
 
mstensho (USE GERRIT)
2014/10/13 11:21:27
Done.
 
rune
2014/10/13 11:25:08
Acknowledged.
 
 | 
| + LayoutPoint offsetFromPaginationLayerToAncestor; | 
| + ancestorLayer->convertToLayerCoords(paginationLayer, offsetFromPaginationLayerToAncestor); | 
| + offsetFromPaginationLayerToAncestor = flowThread->flowThreadPointToVisualPoint(offsetFromPaginationLayerToAncestor); | 
| + rect.moveBy(-offsetFromPaginationLayerToAncestor); | 
| +} | 
| + | 
| bool RenderLayer::useRegionBasedColumns() const | 
| { | 
| return renderer()->document().regionBasedColumnsEnabled(); | 
| @@ -2242,16 +2274,7 @@ LayoutRect RenderLayer::fragmentsBoundingBox(const RenderLayer* ancestorLayer) c | 
| return physicalBoundingBox(ancestorLayer); | 
| LayoutRect result = flippedLogicalBoundingBox(); | 
| - | 
| - // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to | 
| - // get our true bounding box. | 
| - LayoutPoint offsetWithinPaginationLayer; | 
| - convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginationLayer); | 
| - result.moveBy(offsetWithinPaginationLayer); | 
| - | 
| - RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer()); | 
| - result = enclosingFlowThread->fragmentsBoundingBox(result); | 
| - enclosingPaginationLayer()->convertToLayerCoords(ancestorLayer, result); | 
| + convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer, result); | 
| return result; | 
| } | 
| @@ -2316,40 +2339,36 @@ LayoutRect RenderLayer::boundingBoxForCompositing(const RenderLayer* ancestorLay | 
| const bool shouldIncludeTransform = paintsWithTransform(PaintBehaviorNormal) || (options == ApplyBoundsChickenEggHacks && transform()); | 
| - LayoutRect localClipRect = clipper().localClipRect(); | 
| - if (localClipRect != PaintInfo::infiniteRect()) { | 
| - if (shouldIncludeTransform) | 
| - localClipRect = transform()->mapRect(localClipRect); | 
| + LayoutRect result = clipper().localClipRect(); | 
| + if (result == PaintInfo::infiniteRect()) { | 
| + LayoutPoint origin; | 
| + result = physicalBoundingBox(ancestorLayer, &origin); | 
| - LayoutPoint delta; | 
| - convertToLayerCoords(ancestorLayer, delta); | 
| - localClipRect.moveBy(delta); | 
| - return localClipRect; | 
| - } | 
| - | 
| - LayoutPoint origin; | 
| - LayoutRect result = physicalBoundingBox(ancestorLayer, &origin); | 
| - | 
| - const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded(); | 
| + const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded(); | 
| - // Reflections are implemented with RenderLayers that hang off of the reflected layer. However, | 
| - // the reflection layer subtree does not include the subtree of the parent RenderLayer, so | 
| - // a recursive computation of stacking children yields no results. This breaks cases when there are stacking | 
| - // children of the parent, that need to be included in reflected composited bounds. | 
| - // Fix this by including composited bounds of stacking children of the reflected RenderLayer. | 
| - if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo() && parent()->reflectionInfo()->reflectionLayer() == this) | 
| - expandRectForReflectionAndStackingChildren(parent(), options, result); | 
| - else | 
| - expandRectForReflectionAndStackingChildren(this, options, result); | 
| + // Reflections are implemented with RenderLayers that hang off of the reflected layer. However, | 
| + // the reflection layer subtree does not include the subtree of the parent RenderLayer, so | 
| + // a recursive computation of stacking children yields no results. This breaks cases when there are stacking | 
| + // children of the parent, that need to be included in reflected composited bounds. | 
| + // Fix this by including composited bounds of stacking children of the reflected RenderLayer. | 
| + if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo() && parent()->reflectionInfo()->reflectionLayer() == this) | 
| + expandRectForReflectionAndStackingChildren(parent(), options, result); | 
| + else | 
| + expandRectForReflectionAndStackingChildren(this, options, result); | 
| - // FIXME: We can optimize the size of the composited layers, by not enlarging | 
| - // filtered areas with the outsets if we know that the filter is going to render in hardware. | 
| - // https://bugs.webkit.org/show_bug.cgi?id=81239 | 
| - m_renderer->style()->filterOutsets().expandRect(result); | 
| + // FIXME: We can optimize the size of the composited layers, by not enlarging | 
| + // filtered areas with the outsets if we know that the filter is going to render in hardware. | 
| + // https://bugs.webkit.org/show_bug.cgi?id=81239 | 
| + m_renderer->style()->filterOutsets().expandRect(result); | 
| + } | 
| if (shouldIncludeTransform) | 
| result = transform()->mapRect(result); | 
| + if (enclosingPaginationLayer()) { | 
| + convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer, result); | 
| + return result; | 
| + } | 
| LayoutPoint delta; | 
| convertToLayerCoords(ancestorLayer, delta); | 
| result.moveBy(delta); |