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); |