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 |