Chromium Code Reviews| Index: Source/core/rendering/RenderLayer.cpp |
| diff --git a/Source/core/rendering/RenderLayer.cpp b/Source/core/rendering/RenderLayer.cpp |
| index 4740c6fccc81bdec03aaafa894272e3e713b7de6..3ff5227af12e3eb66aceb4b5cd2444d3509124c4 100644 |
| --- a/Source/core/rendering/RenderLayer.cpp |
| +++ b/Source/core/rendering/RenderLayer.cpp |
| @@ -439,7 +439,18 @@ static bool checkContainingBlockChainForPagination(RenderLayerModelObject* rende |
| static void convertFromFlowThreadToVisualBoundingBoxInAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutRect& rect) |
| { |
| RenderLayer* paginationLayer = layer->enclosingPaginationLayer(); |
| - ASSERT(paginationLayer); |
| + if (paginationLayer == layer) { |
| + // If |layer| is the flow thread, we want to convert and translate the rectangle with |
| + // respect to the ancestor flow thread (pagination layer), if any. This typically happens |
| + // when this function is called recursively. |
| + if (ancestorLayer == paginationLayer) |
| + return; // But if we've got to the layer where we should stop, do so. |
| + paginationLayer = layer->parent()->enclosingPaginationLayer(); |
| + } |
| + if (!paginationLayer) { |
| + layer->convertToLayerCoords(ancestorLayer, rect); |
| + return; |
| + } |
| RenderFlowThread* flowThread = toRenderFlowThread(paginationLayer->renderer()); |
| // First make the flow thread rectangle relative to the flow thread, not to |layer|. |
| @@ -453,15 +464,16 @@ static void convertFromFlowThreadToVisualBoundingBoxInAncestor(const RenderLayer |
| rect = flowThread->fragmentsBoundingBox(rect); |
| // Finally, make the visual rectangle relative to |ancestorLayer|. |
| - // FIXME: Handle nested fragmentation contexts (crbug.com/423076). 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); |
| + if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { |
|
chrishtr
2014/12/19 19:42:27
Why do you need the recursion both here and in vis
mstensho (USE GERRIT)
2015/01/06 21:35:10
Ideally, we should break the rectangle into a boun
|
| + // If we're inside a nested fragmentation context, for each ancestor fragmentation context |
| + // we have to examine, we need to do another flow-thread-to-visual translation of both the |
| + // offset and the bounding box. If this is the outermost or only fragmentation context, on |
| + // the other hand, we just translate the rectangle to make it relative to |ancestorLayer|. |
| + convertFromFlowThreadToVisualBoundingBoxInAncestor(paginationLayer, ancestorLayer, rect); |
| return; |
| } |
| - // The ancestor layer is also inside the pagination layer, so we need to subtract the visual |
| - // distance from the ancestor layer to the pagination layer. |
| + // The ancestor layer is inside the same pagination layer as |layer|, so we need to subtract |
| + // the visual distance from the ancestor layer to the pagination layer. |
| rect.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer)); |
| } |
| @@ -1453,9 +1465,13 @@ void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutR |
| LayoutPoint RenderLayer::visualOffsetFromAncestor(const RenderLayer* ancestorLayer) const |
| { |
| - RenderLayer* paginationLayer = enclosingPaginationLayer(); |
| LayoutPoint offset; |
| - if (!paginationLayer || paginationLayer == this) { |
| + if (ancestorLayer == this) |
| + return offset; |
| + RenderLayer* paginationLayer = enclosingPaginationLayer(); |
| + if (paginationLayer == this) |
| + paginationLayer = parent()->enclosingPaginationLayer(); |
| + if (!paginationLayer) { |
| convertToLayerCoords(ancestorLayer, offset); |
| return offset; |
| } |
| @@ -1466,10 +1482,7 @@ LayoutPoint RenderLayer::visualOffsetFromAncestor(const RenderLayer* ancestorLay |
| if (ancestorLayer == paginationLayer) |
| return offset; |
| - // FIXME: Handle nested fragmentation contexts (crbug.com/423076). 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. |
| + if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { |
| offset.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); |
| } else { |
| // The ancestor layer is also inside the pagination layer, so we need to subtract the visual |
| @@ -1555,16 +1568,13 @@ void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* |
| // Make the dirty rect relative to the fragmentation context (multicol container, etc.). |
| RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer()); |
| - LayoutPoint offsetOfPaginationLayerFromRoot; |
| - // FIXME: more work needed if there are nested pagination layers. |
| - if (rootLayer != enclosingPaginationLayer() && rootLayer->enclosingPaginationLayer() == enclosingPaginationLayer()) { |
| - // The root layer is inside the fragmentation context. So we need to look inside it and find |
| - // the visual offset from the fragmentation context. |
| - LayoutPoint flowThreadOffset; |
| - rootLayer->convertToLayerCoords(enclosingPaginationLayer(), flowThreadOffset); |
| - offsetOfPaginationLayerFromRoot = -enclosingFlowThread->flowThreadPointToVisualPoint(flowThreadOffset); |
| + LayoutPoint offsetOfPaginationLayerFromRoot; // Visual offset from the root layer to the nearest fragmentation context. |
| + if (rootLayer->enclosingPaginationLayer() == enclosingPaginationLayer()) { |
| + // The root layer is in the same fragmentation context as this layer, so we need to look |
| + // inside it and subtract the offset between the fragmentation context and the root layer. |
| + offsetOfPaginationLayerFromRoot = -rootLayer->visualOffsetFromAncestor(enclosingPaginationLayer()); |
| } else { |
| - enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot); |
| + offsetOfPaginationLayerFromRoot = enclosingPaginationLayer()->visualOffsetFromAncestor(rootLayer); |
| } |
| LayoutRect dirtyRectInFlowThread(dirtyRect); |
| dirtyRectInFlowThread.moveBy(-offsetOfPaginationLayerFromRoot); |