OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. |
3 * | 3 * |
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
5 * | 5 * |
6 * Other contributors: | 6 * Other contributors: |
7 * Robert O'Callahan <roc+@cs.cmu.edu> | 7 * Robert O'Callahan <roc+@cs.cmu.edu> |
8 * David Baron <dbaron@fas.harvard.edu> | 8 * David Baron <dbaron@fas.harvard.edu> |
9 * Christian Biesinger <cbiesinger@web.de> | 9 * Christian Biesinger <cbiesinger@web.de> |
10 * Randall Jesup <rjesup@wgate.com> | 10 * Randall Jesup <rjesup@wgate.com> |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 | 429 |
430 // If the previous block is absolutely positioned, then we can't be paginate
d by the columns block. | 430 // If the previous block is absolutely positioned, then we can't be paginate
d by the columns block. |
431 if (prevBlock->isOutOfFlowPositioned()) | 431 if (prevBlock->isOutOfFlowPositioned()) |
432 return false; | 432 return false; |
433 | 433 |
434 // Otherwise we are paginated by the columns block. | 434 // Otherwise we are paginated by the columns block. |
435 return true; | 435 return true; |
436 } | 436 } |
437 | 437 |
438 // Convert a bounding box from flow thread coordinates, relative to |layer|, to
visual coordinates, relative to |ancestorLayer|. | 438 // Convert a bounding box from flow thread coordinates, relative to |layer|, to
visual coordinates, relative to |ancestorLayer|. |
| 439 // See http://www.chromium.org/developers/design-documents/multi-column-layout f
or more info on these coordinate types. |
439 static void convertFromFlowThreadToVisualBoundingBoxInAncestor(const RenderLayer
* layer, const RenderLayer* ancestorLayer, LayoutRect& rect) | 440 static void convertFromFlowThreadToVisualBoundingBoxInAncestor(const RenderLayer
* layer, const RenderLayer* ancestorLayer, LayoutRect& rect) |
440 { | 441 { |
441 RenderLayer* paginationLayer = layer->enclosingPaginationLayer(); | 442 RenderLayer* paginationLayer = layer->enclosingPaginationLayer(); |
442 ASSERT(paginationLayer); | 443 ASSERT(paginationLayer); |
443 RenderFlowThread* flowThread = toRenderFlowThread(paginationLayer->renderer(
)); | 444 RenderFlowThread* flowThread = toRenderFlowThread(paginationLayer->renderer(
)); |
444 | 445 |
445 // First make the flow thread rectangle relative to the flow thread, not to
|layer|. | 446 // First make the flow thread rectangle relative to the flow thread, not to
|layer|. |
446 LayoutPoint offsetWithinPaginationLayer; | 447 LayoutPoint offsetWithinPaginationLayer; |
447 layer->convertToLayerCoords(paginationLayer, offsetWithinPaginationLayer); | 448 layer->convertToLayerCoords(paginationLayer, offsetWithinPaginationLayer); |
448 rect.moveBy(offsetWithinPaginationLayer); | 449 rect.moveBy(offsetWithinPaginationLayer); |
449 | 450 |
450 // Then make the rectangle visual, relative to the fragmentation context. Sp
lit our box up into | 451 // Then make the rectangle visual, relative to the fragmentation context. Sp
lit our box up into |
451 // the actual fragment boxes that render in the columns/pages and unite thos
e together to get | 452 // the actual fragment boxes that render in the columns/pages and unite thos
e together to get |
452 // our true bounding box. | 453 // our true bounding box. |
453 rect = flowThread->fragmentsBoundingBox(rect); | 454 rect = flowThread->fragmentsBoundingBox(rect); |
454 | 455 |
455 // Finally, make the visual rectangle relative to |ancestorLayer|. | 456 // Finally, make the visual rectangle relative to |ancestorLayer|. |
456 // FIXME: Handle nested fragmentation contexts (crbug.com/423076). For now j
ust give up if there | 457 if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { |
457 // are different pagination layers involved. | 458 rect.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); |
458 if (!ancestorLayer->enclosingPaginationLayer() || ancestorLayer->enclosingPa
ginationLayer() != paginationLayer) { | |
459 // The easy case. The ancestor layer is not within the pagination layer. | |
460 paginationLayer->convertToLayerCoords(ancestorLayer, rect); | |
461 return; | 459 return; |
462 } | 460 } |
463 // The ancestor layer is also inside the pagination layer, so we need to sub
tract the visual | 461 // The ancestor layer is inside the same pagination layer as |layer|, so we
need to subtract |
464 // distance from the ancestor layer to the pagination layer. | 462 // the visual distance from the ancestor layer to the pagination layer. |
465 rect.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer)); | 463 rect.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer)); |
466 } | 464 } |
467 | 465 |
468 bool RenderLayer::useRegionBasedColumns() const | 466 bool RenderLayer::useRegionBasedColumns() const |
469 { | 467 { |
470 return renderer()->document().regionBasedColumnsEnabled(); | 468 return renderer()->document().regionBasedColumnsEnabled(); |
471 } | 469 } |
472 | 470 |
473 void RenderLayer::updatePaginationRecursive(bool needsPaginationUpdate) | 471 void RenderLayer::updatePaginationRecursive(bool needsPaginationUpdate) |
474 { | 472 { |
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1446 | 1444 |
1447 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutR
ect& rect) const | 1445 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutR
ect& rect) const |
1448 { | 1446 { |
1449 LayoutPoint delta; | 1447 LayoutPoint delta; |
1450 convertToLayerCoords(ancestorLayer, delta); | 1448 convertToLayerCoords(ancestorLayer, delta); |
1451 rect.moveBy(delta); | 1449 rect.moveBy(delta); |
1452 } | 1450 } |
1453 | 1451 |
1454 LayoutPoint RenderLayer::visualOffsetFromAncestor(const RenderLayer* ancestorLay
er) const | 1452 LayoutPoint RenderLayer::visualOffsetFromAncestor(const RenderLayer* ancestorLay
er) const |
1455 { | 1453 { |
| 1454 LayoutPoint offset; |
| 1455 if (ancestorLayer == this) |
| 1456 return offset; |
1456 RenderLayer* paginationLayer = enclosingPaginationLayer(); | 1457 RenderLayer* paginationLayer = enclosingPaginationLayer(); |
1457 LayoutPoint offset; | 1458 if (paginationLayer == this) |
1458 if (!paginationLayer || paginationLayer == this) { | 1459 paginationLayer = parent()->enclosingPaginationLayer(); |
| 1460 if (!paginationLayer) { |
1459 convertToLayerCoords(ancestorLayer, offset); | 1461 convertToLayerCoords(ancestorLayer, offset); |
1460 return offset; | 1462 return offset; |
1461 } | 1463 } |
1462 | 1464 |
1463 RenderFlowThread* flowThread = toRenderFlowThread(paginationLayer->renderer(
)); | 1465 RenderFlowThread* flowThread = toRenderFlowThread(paginationLayer->renderer(
)); |
1464 convertToLayerCoords(paginationLayer, offset); | 1466 convertToLayerCoords(paginationLayer, offset); |
1465 offset = flowThread->flowThreadPointToVisualPoint(offset); | 1467 offset = flowThread->flowThreadPointToVisualPoint(offset); |
1466 if (ancestorLayer == paginationLayer) | 1468 if (ancestorLayer == paginationLayer) |
1467 return offset; | 1469 return offset; |
1468 | 1470 |
1469 // FIXME: Handle nested fragmentation contexts (crbug.com/423076). For now j
ust give up if there | 1471 if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { |
1470 // are different pagination layers involved. | |
1471 if (!ancestorLayer->enclosingPaginationLayer() || ancestorLayer->enclosingPa
ginationLayer() != paginationLayer) { | |
1472 // The easy case. The ancestor layer is not within the pagination layer. | |
1473 offset.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); | 1472 offset.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); |
1474 } else { | 1473 } else { |
1475 // The ancestor layer is also inside the pagination layer, so we need to
subtract the visual | 1474 // The ancestor layer is also inside the pagination layer, so we need to
subtract the visual |
1476 // distance from the ancestor layer to the pagination layer. | 1475 // distance from the ancestor layer to the pagination layer. |
1477 offset.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer))
; | 1476 offset.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer))
; |
1478 } | 1477 } |
1479 return offset; | 1478 return offset; |
1480 } | 1479 } |
1481 | 1480 |
1482 void RenderLayer::didUpdateNeedsCompositedScrolling() | 1481 void RenderLayer::didUpdateNeedsCompositedScrolling() |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 ClipRect outlineRectInFlowThread; | 1547 ClipRect outlineRectInFlowThread; |
1549 clipper().calculateRects(paginationClipRectsContext, LayoutRect::infiniteInt
Rect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlo
wThread, | 1548 clipper().calculateRects(paginationClipRectsContext, LayoutRect::infiniteInt
Rect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlo
wThread, |
1550 outlineRectInFlowThread, &offsetWithinPaginatedLayer); | 1549 outlineRectInFlowThread, &offsetWithinPaginatedLayer); |
1551 | 1550 |
1552 // Take our bounding box within the flow thread and clip it. | 1551 // Take our bounding box within the flow thread and clip it. |
1553 LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingB
ox : physicalBoundingBox(enclosingPaginationLayer(), &offsetWithinPaginatedLayer
); | 1552 LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingB
ox : physicalBoundingBox(enclosingPaginationLayer(), &offsetWithinPaginatedLayer
); |
1554 layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect()); | 1553 layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect()); |
1555 | 1554 |
1556 // Make the dirty rect relative to the fragmentation context (multicol conta
iner, etc.). | 1555 // Make the dirty rect relative to the fragmentation context (multicol conta
iner, etc.). |
1557 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginati
onLayer()->renderer()); | 1556 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginati
onLayer()->renderer()); |
1558 LayoutPoint offsetOfPaginationLayerFromRoot; | 1557 LayoutPoint offsetOfPaginationLayerFromRoot; // Visual offset from the root
layer to the nearest fragmentation context. |
1559 // FIXME: more work needed if there are nested pagination layers. | 1558 if (rootLayer->enclosingPaginationLayer() == enclosingPaginationLayer()) { |
1560 if (rootLayer != enclosingPaginationLayer() && rootLayer->enclosingPaginatio
nLayer() == enclosingPaginationLayer()) { | 1559 // The root layer is in the same fragmentation context as this layer, so
we need to look |
1561 // The root layer is inside the fragmentation context. So we need to loo
k inside it and find | 1560 // inside it and subtract the offset between the fragmentation context a
nd the root layer. |
1562 // the visual offset from the fragmentation context. | 1561 offsetOfPaginationLayerFromRoot = -rootLayer->visualOffsetFromAncestor(e
nclosingPaginationLayer()); |
1563 LayoutPoint flowThreadOffset; | |
1564 rootLayer->convertToLayerCoords(enclosingPaginationLayer(), flowThreadOf
fset); | |
1565 offsetOfPaginationLayerFromRoot = -enclosingFlowThread->flowThreadPointT
oVisualPoint(flowThreadOffset); | |
1566 } else { | 1562 } else { |
1567 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPagi
nationLayerFromRoot); | 1563 offsetOfPaginationLayerFromRoot = enclosingPaginationLayer()->visualOffs
etFromAncestor(rootLayer); |
1568 } | 1564 } |
1569 LayoutRect dirtyRectInFlowThread(dirtyRect); | 1565 LayoutRect dirtyRectInFlowThread(dirtyRect); |
1570 dirtyRectInFlowThread.moveBy(-offsetOfPaginationLayerFromRoot); | 1566 dirtyRectInFlowThread.moveBy(-offsetOfPaginationLayerFromRoot); |
1571 | 1567 |
1572 // Tell the flow thread to collect the fragments. We pass enough information
to create a minimal number of fragments based off the pages/columns | 1568 // Tell the flow thread to collect the fragments. We pass enough information
to create a minimal number of fragments based off the pages/columns |
1573 // that intersect the actual dirtyRect as well as the pages/columns that int
ersect our layer's bounding box. | 1569 // that intersect the actual dirtyRect as well as the pages/columns that int
ersect our layer's bounding box. |
1574 enclosingFlowThread->collectLayerFragments(fragments, layerBoundingBoxInFlow
Thread, dirtyRectInFlowThread); | 1570 enclosingFlowThread->collectLayerFragments(fragments, layerBoundingBoxInFlow
Thread, dirtyRectInFlowThread); |
1575 | 1571 |
1576 if (fragments.isEmpty()) | 1572 if (fragments.isEmpty()) |
1577 return; | 1573 return; |
(...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2900 } | 2896 } |
2901 } | 2897 } |
2902 | 2898 |
2903 void showLayerTree(const blink::RenderObject* renderer) | 2899 void showLayerTree(const blink::RenderObject* renderer) |
2904 { | 2900 { |
2905 if (!renderer) | 2901 if (!renderer) |
2906 return; | 2902 return; |
2907 showLayerTree(renderer->enclosingLayer()); | 2903 showLayerTree(renderer->enclosingLayer()); |
2908 } | 2904 } |
2909 #endif | 2905 #endif |
OLD | NEW |