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 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 #endif | 424 #endif |
425 | 425 |
426 DeprecatedPaintLayerStackingNodeIterator iterator(*m_paintLayer.stackingNode
(), childrenToVisit); | 426 DeprecatedPaintLayerStackingNodeIterator iterator(*m_paintLayer.stackingNode
(), childrenToVisit); |
427 while (DeprecatedPaintLayerStackingNode* child = iterator.next()) { | 427 while (DeprecatedPaintLayerStackingNode* child = iterator.next()) { |
428 DeprecatedPaintLayerPainter childPainter(*child->layer()); | 428 DeprecatedPaintLayerPainter childPainter(*child->layer()); |
429 // If this Layer should paint into its own backing or a grouped backing,
that will be done via CompositedDeprecatedPaintLayerMapping::paintContents() | 429 // If this Layer should paint into its own backing or a grouped backing,
that will be done via CompositedDeprecatedPaintLayerMapping::paintContents() |
430 // and CompositedDeprecatedPaintLayerMapping::doPaintTask(). | 430 // and CompositedDeprecatedPaintLayerMapping::doPaintTask(). |
431 if (!childPainter.shouldPaintLayerInSoftwareMode(paintingInfo, paintFlag
s)) | 431 if (!childPainter.shouldPaintLayerInSoftwareMode(paintingInfo, paintFlag
s)) |
432 continue; | 432 continue; |
433 | 433 |
434 if (!child->layer()->isPaginated()) | 434 childPainter.paintLayer(context, paintingInfo, paintFlags); |
435 childPainter.paintLayer(context, paintingInfo, paintFlags); | |
436 else | |
437 childPainter.paintPaginatedChildLayer(context, paintingInfo, paintFl
ags); | |
438 } | 435 } |
439 } | 436 } |
440 | 437 |
441 // FIXME: inline this. | 438 // FIXME: inline this. |
442 static bool paintForFixedRootBackground(const DeprecatedPaintLayer* layer, Paint
LayerFlags paintFlags) | 439 static bool paintForFixedRootBackground(const DeprecatedPaintLayer* layer, Paint
LayerFlags paintFlags) |
443 { | 440 { |
444 return layer->layoutObject()->isDocumentElement() && (paintFlags & PaintLaye
rPaintingRootBackgroundOnly); | 441 return layer->layoutObject()->isDocumentElement() && (paintFlags & PaintLaye
rPaintingRootBackgroundOnly); |
445 } | 442 } |
446 | 443 |
447 bool DeprecatedPaintLayerPainter::shouldPaintLayerInSoftwareMode(const Deprecate
dPaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) | 444 bool DeprecatedPaintLayerPainter::shouldPaintLayerInSoftwareMode(const Deprecate
dPaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) |
(...skipping 16 matching lines...) Expand all Loading... |
464 | 461 |
465 Optional<LayerClipRecorder> clipRecorder; | 462 Optional<LayerClipRecorder> clipRecorder; |
466 | 463 |
467 if (needsToClip(localPaintingInfo, fragment.backgroundRect)) | 464 if (needsToClip(localPaintingInfo, fragment.backgroundRect)) |
468 clipRecorder.emplace(*context, *m_paintLayer.layoutObject(), Display
Item::ClipLayerOverflowControls, fragment.backgroundRect, &localPaintingInfo, fr
agment.paginationOffset, paintFlags); | 465 clipRecorder.emplace(*context, *m_paintLayer.layoutObject(), Display
Item::ClipLayerOverflowControls, fragment.backgroundRect, &localPaintingInfo, fr
agment.paginationOffset, paintFlags); |
469 if (DeprecatedPaintLayerScrollableArea* scrollableArea = m_paintLayer.sc
rollableArea()) | 466 if (DeprecatedPaintLayerScrollableArea* scrollableArea = m_paintLayer.sc
rollableArea()) |
470 ScrollableAreaPainter(*scrollableArea).paintOverflowControls(context
, roundedIntPoint(toPoint(fragment.layerBounds.location() - m_paintLayer.layoutB
oxLocation())), pixelSnappedIntRect(fragment.backgroundRect.rect()), true); | 467 ScrollableAreaPainter(*scrollableArea).paintOverflowControls(context
, roundedIntPoint(toPoint(fragment.layerBounds.location() - m_paintLayer.layoutB
oxLocation())), pixelSnappedIntRect(fragment.backgroundRect.rect()), true); |
471 } | 468 } |
472 } | 469 } |
473 | 470 |
474 static bool checkContainingBlockChainForPagination(LayoutBoxModelObject* layoutO
bject, LayoutBox* ancestorColumnsLayoutObject) | |
475 { | |
476 LayoutView* view = layoutObject->view(); | |
477 LayoutBoxModelObject* prevBlock = layoutObject; | |
478 LayoutBlock* containingBlock; | |
479 for (containingBlock = layoutObject->containingBlock(); | |
480 containingBlock && containingBlock != view && containingBlock != ancesto
rColumnsLayoutObject; | |
481 containingBlock = containingBlock->containingBlock()) | |
482 prevBlock = containingBlock; | |
483 | |
484 // If the columns block wasn't in our containing block chain, then we aren't
paginated by it. | |
485 if (containingBlock != ancestorColumnsLayoutObject) | |
486 return false; | |
487 | |
488 // If the previous block is absolutely positioned, then we can't be paginate
d by the columns block. | |
489 if (prevBlock->isOutOfFlowPositioned()) | |
490 return false; | |
491 | |
492 // Otherwise we are paginated by the columns block. | |
493 return true; | |
494 } | |
495 | |
496 void DeprecatedPaintLayerPainter::paintPaginatedChildLayer(GraphicsContext* cont
ext, const DeprecatedPaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paint
Flags) | |
497 { | |
498 // We need to do multiple passes, breaking up our child layer into strips. | |
499 Vector<DeprecatedPaintLayer*> columnLayers; | |
500 DeprecatedPaintLayerStackingNode* ancestorNode = m_paintLayer.stackingNode()
->isNormalFlowOnly() ? m_paintLayer.parent()->stackingNode() : m_paintLayer.stac
kingNode()->ancestorStackingContextNode(); | |
501 for (DeprecatedPaintLayer* curr = m_paintLayer.parent(); curr; curr = curr->
parent()) { | |
502 if (curr->layoutObject()->hasColumns() && checkContainingBlockChainForPa
gination(m_paintLayer.layoutObject(), curr->layoutBox())) | |
503 columnLayers.append(curr); | |
504 if (curr->stackingNode() == ancestorNode) | |
505 break; | |
506 } | |
507 | |
508 // It is possible for paintLayer() to be called after the child layer ceases
to be paginated but before | |
509 // updatePaginationRecusive() is called and resets the isPaginated() flag, s
ee <rdar://problem/10098679>. | |
510 // If this is the case, just bail out, since the upcoming call to updatePagi
nationRecusive() will paint invalidate the layer. | |
511 // FIXME: Is this true anymore? This seems very suspicious. | |
512 if (!columnLayers.size()) | |
513 return; | |
514 | |
515 paintChildLayerIntoColumns(context, paintingInfo, paintFlags, columnLayers,
columnLayers.size() - 1); | |
516 } | |
517 | |
518 void DeprecatedPaintLayerPainter::paintChildLayerIntoColumns(GraphicsContext* co
ntext, const DeprecatedPaintLayerPaintingInfo& paintingInfo, | |
519 PaintLayerFlags paintFlags, const Vector<DeprecatedPaintLayer*>& columnLayer
s, size_t colIndex) | |
520 { | |
521 LayoutBlock* columnBlock = toLayoutBlock(columnLayers[colIndex]->layoutObjec
t()); | |
522 | |
523 ASSERT(columnBlock && columnBlock->hasColumns()); | |
524 if (!columnBlock || !columnBlock->hasColumns()) | |
525 return; | |
526 | |
527 LayoutPoint layerOffset; | |
528 // FIXME: It looks suspicious to call convertToLayerCoords here | |
529 // as canUseConvertToLayerCoords is true for this layer. | |
530 columnBlock->layer()->convertToLayerCoords(paintingInfo.rootLayer, layerOffs
et); | |
531 | |
532 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode(); | |
533 | |
534 ColumnInfo* colInfo = columnBlock->columnInfo(); | |
535 unsigned colCount = columnBlock->columnCount(colInfo); | |
536 LayoutUnit currLogicalTopOffset = 0; | |
537 for (unsigned i = 0; i < colCount; i++) { | |
538 // For each rect, we clip to the rect, and then we adjust our coords. | |
539 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i); | |
540 columnBlock->flipForWritingMode(colRect); | |
541 LayoutUnit logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()
) - columnBlock->logicalLeftOffsetForContent(); | |
542 LayoutSize offset; | |
543 if (isHorizontal) { | |
544 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) | |
545 offset = LayoutSize(logicalLeftOffset, currLogicalTopOffset); | |
546 else | |
547 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - colu
mnBlock->borderTop() - columnBlock->paddingTop()); | |
548 } else { | |
549 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) | |
550 offset = LayoutSize(currLogicalTopOffset, logicalLeftOffset); | |
551 else | |
552 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnB
lock->borderLeft() - columnBlock->paddingLeft(), 0); | |
553 } | |
554 | |
555 colRect.moveBy(layerOffset); | |
556 | |
557 LayoutRect localDirtyRect(paintingInfo.paintDirtyRect); | |
558 localDirtyRect.intersect(colRect); | |
559 | |
560 if (!localDirtyRect.isEmpty()) { | |
561 // Each strip pushes a clip, since column boxes are specified as bei
ng | |
562 // like overflow:hidden. | |
563 ClipRecorder clipRecorder(*context, *m_paintLayer.layoutObject(), Di
splayItem::ClipLayerColumnBounds, LayoutRect(enclosingIntRect(colRect))); | |
564 | |
565 if (!colIndex) { | |
566 // Apply a translation transform to change where the layer paint
s. | |
567 TransformationMatrix oldTransform; | |
568 bool oldHasTransform = m_paintLayer.transform(); | |
569 if (oldHasTransform) | |
570 oldTransform = *m_paintLayer.transform(); | |
571 TransformationMatrix newTransform(oldTransform); | |
572 newTransform.translateRight(roundToInt(offset.width()), roundToI
nt(offset.height())); | |
573 | |
574 m_paintLayer.setTransform(adoptPtr(new TransformationMatrix(newT
ransform))); | |
575 | |
576 DeprecatedPaintLayerPaintingInfo localPaintingInfo(paintingInfo)
; | |
577 localPaintingInfo.paintDirtyRect = localDirtyRect; | |
578 paintLayer(context, localPaintingInfo, paintFlags); | |
579 | |
580 if (oldHasTransform) | |
581 m_paintLayer.setTransform(adoptPtr(new TransformationMatrix(
oldTransform))); | |
582 else | |
583 m_paintLayer.clearTransform(); | |
584 } else { | |
585 // Adjust the transform such that the layoutObject's upper left
corner will paint at (0,0) in user space. | |
586 // This involves subtracting out the position of the layer in ou
r current coordinate space. | |
587 LayoutPoint childOffset; | |
588 columnLayers[colIndex - 1]->convertToLayerCoords(paintingInfo.ro
otLayer, childOffset); | |
589 TransformationMatrix transform; | |
590 transform.translateRight(roundToInt(childOffset.x() + offset.wid
th()), roundToInt(childOffset.y() + offset.height())); | |
591 | |
592 Transform3DRecorder transform3DRecorder(*context, *m_paintLayer.
layoutObject(), DisplayItem::Transform3DElementTransform, transform); | |
593 | |
594 // Now do a paint with the root layer shifted to be the next mul
ticol block. | |
595 DeprecatedPaintLayerPaintingInfo columnPaintingInfo(paintingInfo
); | |
596 columnPaintingInfo.rootLayer = columnLayers[colIndex - 1]; | |
597 columnPaintingInfo.paintDirtyRect = transform.inverse().mapRect(
localDirtyRect); | |
598 paintChildLayerIntoColumns(context, columnPaintingInfo, paintFla
gs, columnLayers, colIndex - 1); | |
599 } | |
600 } | |
601 | |
602 // Move to the next position. | |
603 LayoutUnit blockDelta = isHorizontal ? colRect.height() : colRect.width(
); | |
604 if (columnBlock->style()->isFlippedBlocksWritingMode()) | |
605 currLogicalTopOffset += blockDelta; | |
606 else | |
607 currLogicalTopOffset -= blockDelta; | |
608 } | |
609 } | |
610 | |
611 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) | 471 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) |
612 { | 472 { |
613 ASSERT(m_paintLayer.isSelfPaintingLayer()); | 473 ASSERT(m_paintLayer.isSelfPaintingLayer()); |
614 | 474 |
615 Optional<LayerClipRecorder> clipRecorder; | 475 Optional<LayerClipRecorder> clipRecorder; |
616 if (clipState != HasClipped && paintingInfo.clipToDirtyRect && needsToClip(p
aintingInfo, clipRect)) { | 476 if (clipState != HasClipped && paintingInfo.clipToDirtyRect && needsToClip(p
aintingInfo, clipRect)) { |
617 DisplayItem::Type clipType = DisplayItem::paintPhaseToClipLayerFragmentT
ype(phase); | 477 DisplayItem::Type clipType = DisplayItem::paintPhaseToClipLayerFragmentT
ype(phase); |
618 LayerClipRecorder::BorderRadiusClippingRule clippingRule; | 478 LayerClipRecorder::BorderRadiusClippingRule clippingRule; |
619 switch (phase) { | 479 switch (phase) { |
620 case PaintPhaseBlockBackground: // Background painting will handle clipp
ing to self. | 480 case PaintPhaseBlockBackground: // Background painting will handle clipp
ing to self. |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 if (!m_paintLayer.containsDirtyOverlayScrollbars()) | 602 if (!m_paintLayer.containsDirtyOverlayScrollbars()) |
743 return; | 603 return; |
744 | 604 |
745 DeprecatedPaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(encl
osingIntRect(damageRect)), paintBehavior, LayoutSize(), paintingRoot); | 605 DeprecatedPaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(encl
osingIntRect(damageRect)), paintBehavior, LayoutSize(), paintingRoot); |
746 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 606 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
747 | 607 |
748 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 608 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
749 } | 609 } |
750 | 610 |
751 } // namespace blink | 611 } // namespace blink |
OLD | NEW |