| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/paint/DeprecatedPaintLayerPainter.h" | 6 #include "core/paint/DeprecatedPaintLayerPainter.h" |
| 7 | 7 |
| 8 #include "core/frame/Settings.h" | 8 #include "core/frame/Settings.h" |
| 9 #include "core/layout/ClipPathOperation.h" | 9 #include "core/layout/ClipPathOperation.h" |
| 10 #include "core/layout/LayoutBlock.h" | 10 #include "core/layout/LayoutBlock.h" |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 continue; | 437 continue; |
| 438 | 438 |
| 439 DeprecatedPaintLayerPaintingInfo childPaintingInfo = paintingInfo; | 439 DeprecatedPaintLayerPaintingInfo childPaintingInfo = paintingInfo; |
| 440 childPaintingInfo.scrollOffsetAccumulation = scrollOffsetAccumulation; | 440 childPaintingInfo.scrollOffsetAccumulation = scrollOffsetAccumulation; |
| 441 // Rare case: accumulate scroll offset of non-stacking-context ancestors
up to m_paintLayer. | 441 // Rare case: accumulate scroll offset of non-stacking-context ancestors
up to m_paintLayer. |
| 442 for (DeprecatedPaintLayer* parentLayer = child->layer()->parent(); paren
tLayer != &m_paintLayer; parentLayer = parentLayer->parent()) { | 442 for (DeprecatedPaintLayer* parentLayer = child->layer()->parent(); paren
tLayer != &m_paintLayer; parentLayer = parentLayer->parent()) { |
| 443 if (parentLayer->layoutObject()->hasOverflowClip()) | 443 if (parentLayer->layoutObject()->hasOverflowClip()) |
| 444 childPaintingInfo.scrollOffsetAccumulation += parentLayer->layou
tBox()->scrolledContentOffset(); | 444 childPaintingInfo.scrollOffsetAccumulation += parentLayer->layou
tBox()->scrolledContentOffset(); |
| 445 } | 445 } |
| 446 | 446 |
| 447 if (!child->layer()->isPaginated()) | 447 childPainter.paintLayer(context, childPaintingInfo, paintFlags); |
| 448 childPainter.paintLayer(context, childPaintingInfo, paintFlags); | |
| 449 else | |
| 450 childPainter.paintPaginatedChildLayer(context, childPaintingInfo, pa
intFlags); | |
| 451 } | 448 } |
| 452 } | 449 } |
| 453 | 450 |
| 454 // FIXME: inline this. | 451 // FIXME: inline this. |
| 455 static bool paintForFixedRootBackground(const DeprecatedPaintLayer* layer, Paint
LayerFlags paintFlags) | 452 static bool paintForFixedRootBackground(const DeprecatedPaintLayer* layer, Paint
LayerFlags paintFlags) |
| 456 { | 453 { |
| 457 return layer->layoutObject()->isDocumentElement() && (paintFlags & PaintLaye
rPaintingRootBackgroundOnly); | 454 return layer->layoutObject()->isDocumentElement() && (paintFlags & PaintLaye
rPaintingRootBackgroundOnly); |
| 458 } | 455 } |
| 459 | 456 |
| 460 bool DeprecatedPaintLayerPainter::shouldPaintLayerInSoftwareMode(const Deprecate
dPaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) | 457 bool DeprecatedPaintLayerPainter::shouldPaintLayerInSoftwareMode(const Deprecate
dPaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 477 | 474 |
| 478 Optional<LayerClipRecorder> clipRecorder; | 475 Optional<LayerClipRecorder> clipRecorder; |
| 479 | 476 |
| 480 if (needsToClip(localPaintingInfo, fragment.backgroundRect)) | 477 if (needsToClip(localPaintingInfo, fragment.backgroundRect)) |
| 481 clipRecorder.emplace(*context, *m_paintLayer.layoutObject(), Display
Item::ClipLayerOverflowControls, fragment.backgroundRect, &localPaintingInfo, fr
agment.paginationOffset, paintFlags); | 478 clipRecorder.emplace(*context, *m_paintLayer.layoutObject(), Display
Item::ClipLayerOverflowControls, fragment.backgroundRect, &localPaintingInfo, fr
agment.paginationOffset, paintFlags); |
| 482 if (DeprecatedPaintLayerScrollableArea* scrollableArea = m_paintLayer.sc
rollableArea()) | 479 if (DeprecatedPaintLayerScrollableArea* scrollableArea = m_paintLayer.sc
rollableArea()) |
| 483 ScrollableAreaPainter(*scrollableArea).paintOverflowControls(context
, roundedIntPoint(toPoint(fragment.layerBounds.location() - m_paintLayer.layoutB
oxLocation())), pixelSnappedIntRect(fragment.backgroundRect.rect()), true); | 480 ScrollableAreaPainter(*scrollableArea).paintOverflowControls(context
, roundedIntPoint(toPoint(fragment.layerBounds.location() - m_paintLayer.layoutB
oxLocation())), pixelSnappedIntRect(fragment.backgroundRect.rect()), true); |
| 484 } | 481 } |
| 485 } | 482 } |
| 486 | 483 |
| 487 static bool checkContainingBlockChainForPagination(LayoutBoxModelObject* layoutO
bject, LayoutBox* ancestorColumnsLayoutObject) | |
| 488 { | |
| 489 LayoutView* view = layoutObject->view(); | |
| 490 LayoutBoxModelObject* prevBlock = layoutObject; | |
| 491 LayoutBlock* containingBlock; | |
| 492 for (containingBlock = layoutObject->containingBlock(); | |
| 493 containingBlock && containingBlock != view && containingBlock != ancesto
rColumnsLayoutObject; | |
| 494 containingBlock = containingBlock->containingBlock()) | |
| 495 prevBlock = containingBlock; | |
| 496 | |
| 497 // If the columns block wasn't in our containing block chain, then we aren't
paginated by it. | |
| 498 if (containingBlock != ancestorColumnsLayoutObject) | |
| 499 return false; | |
| 500 | |
| 501 // If the previous block is absolutely positioned, then we can't be paginate
d by the columns block. | |
| 502 if (prevBlock->isOutOfFlowPositioned()) | |
| 503 return false; | |
| 504 | |
| 505 // Otherwise we are paginated by the columns block. | |
| 506 return true; | |
| 507 } | |
| 508 | |
| 509 void DeprecatedPaintLayerPainter::paintPaginatedChildLayer(GraphicsContext* cont
ext, const DeprecatedPaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paint
Flags) | |
| 510 { | |
| 511 // We need to do multiple passes, breaking up our child layer into strips. | |
| 512 Vector<DeprecatedPaintLayer*> columnLayers; | |
| 513 DeprecatedPaintLayerStackingNode* ancestorNode = m_paintLayer.stackingNode()
->isNormalFlowOnly() ? m_paintLayer.parent()->stackingNode() : m_paintLayer.stac
kingNode()->ancestorStackingContextNode(); | |
| 514 for (DeprecatedPaintLayer* curr = m_paintLayer.parent(); curr; curr = curr->
parent()) { | |
| 515 if (curr->layoutObject()->hasColumns() && checkContainingBlockChainForPa
gination(m_paintLayer.layoutObject(), curr->layoutBox())) | |
| 516 columnLayers.append(curr); | |
| 517 if (curr->stackingNode() == ancestorNode) | |
| 518 break; | |
| 519 } | |
| 520 | |
| 521 // It is possible for paintLayer() to be called after the child layer ceases
to be paginated but before | |
| 522 // updatePaginationRecusive() is called and resets the isPaginated() flag, s
ee <rdar://problem/10098679>. | |
| 523 // If this is the case, just bail out, since the upcoming call to updatePagi
nationRecusive() will paint invalidate the layer. | |
| 524 // FIXME: Is this true anymore? This seems very suspicious. | |
| 525 if (!columnLayers.size()) | |
| 526 return; | |
| 527 | |
| 528 paintChildLayerIntoColumns(context, paintingInfo, paintFlags, columnLayers,
columnLayers.size() - 1); | |
| 529 } | |
| 530 | |
| 531 void DeprecatedPaintLayerPainter::paintChildLayerIntoColumns(GraphicsContext* co
ntext, const DeprecatedPaintLayerPaintingInfo& paintingInfo, | |
| 532 PaintLayerFlags paintFlags, const Vector<DeprecatedPaintLayer*>& columnLayer
s, size_t colIndex) | |
| 533 { | |
| 534 LayoutBlock* columnBlock = toLayoutBlock(columnLayers[colIndex]->layoutObjec
t()); | |
| 535 | |
| 536 ASSERT(columnBlock && columnBlock->hasColumns()); | |
| 537 if (!columnBlock || !columnBlock->hasColumns()) | |
| 538 return; | |
| 539 | |
| 540 LayoutPoint layerOffset; | |
| 541 // FIXME: It looks suspicious to call convertToLayerCoords here | |
| 542 // as canUseConvertToLayerCoords is true for this layer. | |
| 543 columnBlock->layer()->convertToLayerCoords(paintingInfo.rootLayer, layerOffs
et); | |
| 544 | |
| 545 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode(); | |
| 546 | |
| 547 ColumnInfo* colInfo = columnBlock->columnInfo(); | |
| 548 unsigned colCount = columnBlock->columnCount(colInfo); | |
| 549 LayoutUnit currLogicalTopOffset = 0; | |
| 550 for (unsigned i = 0; i < colCount; i++) { | |
| 551 // For each rect, we clip to the rect, and then we adjust our coords. | |
| 552 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i); | |
| 553 columnBlock->flipForWritingMode(colRect); | |
| 554 LayoutUnit logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()
) - columnBlock->logicalLeftOffsetForContent(); | |
| 555 LayoutSize offset; | |
| 556 if (isHorizontal) { | |
| 557 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) | |
| 558 offset = LayoutSize(logicalLeftOffset, currLogicalTopOffset); | |
| 559 else | |
| 560 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - colu
mnBlock->borderTop() - columnBlock->paddingTop()); | |
| 561 } else { | |
| 562 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) | |
| 563 offset = LayoutSize(currLogicalTopOffset, logicalLeftOffset); | |
| 564 else | |
| 565 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnB
lock->borderLeft() - columnBlock->paddingLeft(), 0); | |
| 566 } | |
| 567 | |
| 568 colRect.moveBy(layerOffset); | |
| 569 | |
| 570 LayoutRect localDirtyRect(paintingInfo.paintDirtyRect); | |
| 571 localDirtyRect.intersect(colRect); | |
| 572 | |
| 573 if (!localDirtyRect.isEmpty()) { | |
| 574 // Each strip pushes a clip, since column boxes are specified as bei
ng | |
| 575 // like overflow:hidden. | |
| 576 ClipRecorder clipRecorder(*context, *m_paintLayer.layoutObject(), Di
splayItem::ClipLayerColumnBounds, LayoutRect(enclosingIntRect(colRect))); | |
| 577 | |
| 578 if (!colIndex) { | |
| 579 // Apply a translation transform to change where the layer paint
s. | |
| 580 TransformationMatrix oldTransform; | |
| 581 bool oldHasTransform = m_paintLayer.transform(); | |
| 582 if (oldHasTransform) | |
| 583 oldTransform = *m_paintLayer.transform(); | |
| 584 TransformationMatrix newTransform(oldTransform); | |
| 585 newTransform.translateRight(roundToInt(offset.width()), roundToI
nt(offset.height())); | |
| 586 | |
| 587 m_paintLayer.setTransform(adoptPtr(new TransformationMatrix(newT
ransform))); | |
| 588 | |
| 589 DeprecatedPaintLayerPaintingInfo localPaintingInfo(paintingInfo)
; | |
| 590 localPaintingInfo.paintDirtyRect = localDirtyRect; | |
| 591 paintLayer(context, localPaintingInfo, paintFlags); | |
| 592 | |
| 593 if (oldHasTransform) | |
| 594 m_paintLayer.setTransform(adoptPtr(new TransformationMatrix(
oldTransform))); | |
| 595 else | |
| 596 m_paintLayer.clearTransform(); | |
| 597 } else { | |
| 598 // Adjust the transform such that the layoutObject's upper left
corner will paint at (0,0) in user space. | |
| 599 // This involves subtracting out the position of the layer in ou
r current coordinate space. | |
| 600 LayoutPoint childOffset; | |
| 601 columnLayers[colIndex - 1]->convertToLayerCoords(paintingInfo.ro
otLayer, childOffset); | |
| 602 TransformationMatrix transform; | |
| 603 transform.translateRight(roundToInt(childOffset.x() + offset.wid
th()), roundToInt(childOffset.y() + offset.height())); | |
| 604 | |
| 605 Transform3DRecorder transform3DRecorder(*context, *m_paintLayer.
layoutObject(), DisplayItem::Transform3DElementTransform, transform); | |
| 606 | |
| 607 // Now do a paint with the root layer shifted to be the next mul
ticol block. | |
| 608 DeprecatedPaintLayerPaintingInfo columnPaintingInfo(paintingInfo
); | |
| 609 columnPaintingInfo.rootLayer = columnLayers[colIndex - 1]; | |
| 610 columnPaintingInfo.paintDirtyRect = transform.inverse().mapRect(
localDirtyRect); | |
| 611 paintChildLayerIntoColumns(context, columnPaintingInfo, paintFla
gs, columnLayers, colIndex - 1); | |
| 612 } | |
| 613 } | |
| 614 | |
| 615 // Move to the next position. | |
| 616 LayoutUnit blockDelta = isHorizontal ? colRect.height() : colRect.width(
); | |
| 617 if (columnBlock->style()->isFlippedBlocksWritingMode()) | |
| 618 currLogicalTopOffset += blockDelta; | |
| 619 else | |
| 620 currLogicalTopOffset -= blockDelta; | |
| 621 } | |
| 622 } | |
| 623 | |
| 624 void DeprecatedPaintLayerPainter::paintFragmentWithPhase(PaintPhase phase, const
DeprecatedPaintLayerFragment& fragment, GraphicsContext* context, const ClipRec
t& clipRect, const DeprecatedPaintLayerPaintingInfo& paintingInfo, PaintBehavior
paintBehavior, LayoutObject* paintingRootForLayoutObject, PaintLayerFlags paint
Flags, ClipState clipState) | 484 void DeprecatedPaintLayerPainter::paintFragmentWithPhase(PaintPhase phase, const
DeprecatedPaintLayerFragment& fragment, GraphicsContext* context, const ClipRec
t& clipRect, const DeprecatedPaintLayerPaintingInfo& paintingInfo, PaintBehavior
paintBehavior, LayoutObject* paintingRootForLayoutObject, PaintLayerFlags paint
Flags, ClipState clipState) |
| 625 { | 485 { |
| 626 ASSERT(m_paintLayer.isSelfPaintingLayer()); | 486 ASSERT(m_paintLayer.isSelfPaintingLayer()); |
| 627 | 487 |
| 628 Optional<LayerClipRecorder> clipRecorder; | 488 Optional<LayerClipRecorder> clipRecorder; |
| 629 if (clipState != HasClipped && paintingInfo.clipToDirtyRect && needsToClip(p
aintingInfo, clipRect)) { | 489 if (clipState != HasClipped && paintingInfo.clipToDirtyRect && needsToClip(p
aintingInfo, clipRect)) { |
| 630 DisplayItem::Type clipType = DisplayItem::paintPhaseToClipLayerFragmentT
ype(phase); | 490 DisplayItem::Type clipType = DisplayItem::paintPhaseToClipLayerFragmentT
ype(phase); |
| 631 LayerClipRecorder::BorderRadiusClippingRule clippingRule; | 491 LayerClipRecorder::BorderRadiusClippingRule clippingRule; |
| 632 switch (phase) { | 492 switch (phase) { |
| 633 case PaintPhaseBlockBackground: // Background painting will handle clipp
ing to self. | 493 case PaintPhaseBlockBackground: // Background painting will handle clipp
ing to self. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 if (!m_paintLayer.containsDirtyOverlayScrollbars()) | 613 if (!m_paintLayer.containsDirtyOverlayScrollbars()) |
| 754 return; | 614 return; |
| 755 | 615 |
| 756 DeprecatedPaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(encl
osingIntRect(damageRect)), paintBehavior, LayoutSize(), paintingRoot); | 616 DeprecatedPaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(encl
osingIntRect(damageRect)), paintBehavior, LayoutSize(), paintingRoot); |
| 757 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 617 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
| 758 | 618 |
| 759 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 619 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
| 760 } | 620 } |
| 761 | 621 |
| 762 } // namespace blink | 622 } // namespace blink |
| OLD | NEW |