| Index: third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
|
| diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
|
| index 6e8ab3df4c7c88b64be532c30a0da0e428bb1ac9..865032f7c7a05aad0c4f98bbd7457515e9425416 100644
|
| --- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
|
| +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
|
| @@ -422,8 +422,16 @@ PaintResult PaintLayerPainter::paintLayerContents(
|
| localPaintingInfo.paintDirtyRect, cacheSlot,
|
| IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot,
|
| localPaintingInfo.subPixelAccumulation);
|
| - } else if (!collectPaintFragmentsForPaginatedFixedPosition(
|
| - paintingInfo, layerFragments)) {
|
| + } else if (isFixedPositionObjectInPagedMedia()) {
|
| + PaintLayerFragments singleFragment;
|
| + m_paintLayer.appendSingleFragmentIgnoringPagination(
|
| + singleFragment, localPaintingInfo.rootLayer,
|
| + localPaintingInfo.paintDirtyRect, cacheSlot,
|
| + IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot,
|
| + localPaintingInfo.subPixelAccumulation);
|
| + repeatFixedPositionObjectInPages(singleFragment[0], paintingInfo,
|
| + layerFragments);
|
| + } else {
|
| m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer,
|
| localPaintingInfo.paintDirtyRect, cacheSlot,
|
| IgnoreOverlayScrollbarSize,
|
| @@ -586,40 +594,45 @@ bool PaintLayerPainter::atLeastOneFragmentIntersectsDamageRect(
|
| return false;
|
| }
|
|
|
| -bool PaintLayerPainter::collectPaintFragmentsForPaginatedFixedPosition(
|
| - const PaintLayerPaintingInfo& paintingInfo,
|
| - PaintLayerFragments& layerFragments) {
|
| +inline bool PaintLayerPainter::isFixedPositionObjectInPagedMedia() {
|
| LayoutObject* object = m_paintLayer.layoutObject();
|
| LayoutView* view = object->view();
|
| - bool isFixedPosObjectInPagedMedia =
|
| - object->style()->position() == FixedPosition &&
|
| - object->container() == view && view->pageLogicalHeight();
|
| + return object->styleRef().position() == FixedPosition &&
|
| + object->container() == view && view->pageLogicalHeight() &&
|
| + // TODO(crbug.com/619094): Figure out the correct behaviour for fixed
|
| + // position objects in paged media with vertical writing modes.
|
| + view->isHorizontalWritingMode();
|
| +}
|
|
|
| - // TODO(crbug.com/619094): Figure out the correct behaviour for fixed position
|
| - // objects in paged media with vertical writing modes.
|
| - if (!isFixedPosObjectInPagedMedia || !view->isHorizontalWritingMode())
|
| - return false;
|
| +// "For paged media, boxes with fixed positions are repeated on every page."
|
| +// https://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#fixed-positioning
|
| +// TODO(wangxianzhu): Fold this into PaintLayer::collectFragments().
|
| +void PaintLayerPainter::repeatFixedPositionObjectInPages(
|
| + const PaintLayerFragment& singleFragmentIgnoredPagination,
|
| + const PaintLayerPaintingInfo& paintingInfo,
|
| + PaintLayerFragments& layerFragments) {
|
| + DCHECK(isFixedPositionObjectInPagedMedia());
|
|
|
| - // "For paged media, boxes with fixed positions are repeated on every page."
|
| - // https://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#fixed-positioning
|
| + LayoutView* view = m_paintLayer.layoutObject()->view();
|
| unsigned pages =
|
| ceilf(view->documentRect().height() / view->pageLogicalHeight());
|
| - LayoutPoint paginationOffset;
|
|
|
| // The fixed position object is offset from the top of the page, so remove
|
| // any scroll offset.
|
| LayoutPoint offsetFromRoot;
|
| m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
|
| - paginationOffset -= offsetFromRoot - m_paintLayer.location();
|
| -
|
| - for (unsigned i = 0; i < pages; i++) {
|
| - PaintLayerFragment fragment;
|
| - fragment.backgroundRect = paintingInfo.paintDirtyRect;
|
| - fragment.paginationOffset = paginationOffset;
|
| + LayoutSize offsetAdjustment = m_paintLayer.location() - offsetFromRoot;
|
| + layerFragments.append(singleFragmentIgnoredPagination);
|
| + layerFragments[0].paginationOffset += offsetAdjustment;
|
| + layerFragments[0].layerBounds.move(offsetAdjustment);
|
| +
|
| + LayoutPoint pageOffset(LayoutUnit(), view->pageLogicalHeight());
|
| + for (unsigned i = 1; i < pages; i++) {
|
| + PaintLayerFragment fragment = layerFragments[i - 1];
|
| + fragment.paginationOffset += pageOffset;
|
| + fragment.layerBounds.moveBy(pageOffset);
|
| layerFragments.append(fragment);
|
| - paginationOffset += LayoutPoint(LayoutUnit(), view->pageLogicalHeight());
|
| }
|
| - return true;
|
| }
|
|
|
| PaintResult PaintLayerPainter::paintLayerWithTransform(
|
| @@ -637,48 +650,43 @@ PaintResult PaintLayerPainter::paintLayerWithTransform(
|
| // its parent.
|
| PaintLayer* parentLayer = m_paintLayer.parent();
|
|
|
| - LayoutObject* object = m_paintLayer.layoutObject();
|
| - LayoutView* view = object->view();
|
| - bool isFixedPosObjectInPagedMedia =
|
| - object->style()->position() == FixedPosition &&
|
| - object->container() == view && view->pageLogicalHeight();
|
| PaintLayer* paginationLayer = m_paintLayer.enclosingPaginationLayer();
|
| PaintLayerFragments layerFragments;
|
| - if (!collectPaintFragmentsForPaginatedFixedPosition(paintingInfo,
|
| - layerFragments)) {
|
| - if (paginationLayer) {
|
| - // FIXME: This is a mess. Look closely at this code and the code in Layer
|
| - // and fix any issues in it & refactor to make it obvious from code
|
| - // structure what it does and that it's correct.
|
| - ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects)
|
| - ? UncachedClipRects
|
| - : PaintingClipRects;
|
| - ShouldRespectOverflowClipType respectOverflowClip =
|
| - shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject());
|
| - // Calculate the transformed bounding box in the current coordinate space,
|
| - // to figure out which fragmentainers (e.g. columns) we need to visit.
|
| - LayoutRect transformedExtent = PaintLayer::transparencyClipBox(
|
| - &m_paintLayer, paginationLayer,
|
| - PaintLayer::PaintingTransparencyClipBox,
|
| - PaintLayer::RootOfTransparencyClipBox,
|
| - paintingInfo.subPixelAccumulation,
|
| - paintingInfo.getGlobalPaintFlags());
|
| - // FIXME: we don't check if paginationLayer is within
|
| - // paintingInfo.rootLayer
|
| - // here.
|
| - paginationLayer->collectFragments(
|
| - layerFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect,
|
| - cacheSlot, IgnoreOverlayScrollbarSize, respectOverflowClip, 0,
|
| - paintingInfo.subPixelAccumulation, &transformedExtent);
|
| - } else {
|
| - // We don't need to collect any fragments in the regular way here. We have
|
| - // already calculated a clip rectangle for the ancestry if it was needed,
|
| - // and clipping this layer is something that can be done further down the
|
| - // path, when the transform has been applied.
|
| - PaintLayerFragment fragment;
|
| - fragment.backgroundRect = paintingInfo.paintDirtyRect;
|
| + bool isFixedPositionObjectInPagedMedia =
|
| + this->isFixedPositionObjectInPagedMedia();
|
| + if (!paginationLayer || isFixedPositionObjectInPagedMedia) {
|
| + // We don't need to collect any fragments in the regular way here. We have
|
| + // already calculated a clip rectangle for the ancestry if it was needed,
|
| + // and clipping this layer is something that can be done further down the
|
| + // path, when the transform has been applied.
|
| + PaintLayerFragment fragment;
|
| + fragment.backgroundRect = paintingInfo.paintDirtyRect;
|
| + if (isFixedPositionObjectInPagedMedia)
|
| + repeatFixedPositionObjectInPages(fragment, paintingInfo, layerFragments);
|
| + else
|
| layerFragments.append(fragment);
|
| - }
|
| + } else {
|
| + // FIXME: This is a mess. Look closely at this code and the code in Layer
|
| + // and fix any issues in it & refactor to make it obvious from code
|
| + // structure what it does and that it's correct.
|
| + ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects)
|
| + ? UncachedClipRects
|
| + : PaintingClipRects;
|
| + ShouldRespectOverflowClipType respectOverflowClip =
|
| + shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject());
|
| + // Calculate the transformed bounding box in the current coordinate space,
|
| + // to figure out which fragmentainers (e.g. columns) we need to visit.
|
| + LayoutRect transformedExtent = PaintLayer::transparencyClipBox(
|
| + &m_paintLayer, paginationLayer, PaintLayer::PaintingTransparencyClipBox,
|
| + PaintLayer::RootOfTransparencyClipBox,
|
| + paintingInfo.subPixelAccumulation, paintingInfo.getGlobalPaintFlags());
|
| + // FIXME: we don't check if paginationLayer is within
|
| + // paintingInfo.rootLayer
|
| + // here.
|
| + paginationLayer->collectFragments(
|
| + layerFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect,
|
| + cacheSlot, IgnoreOverlayScrollbarSize, respectOverflowClip, nullptr,
|
| + paintingInfo.subPixelAccumulation, &transformedExtent);
|
| }
|
|
|
| Optional<DisplayItemCacheSkipper> cacheSkipper;
|
| @@ -707,9 +715,9 @@ PaintResult PaintLayerPainter::paintLayerWithTransform(
|
| Optional<LayerClipRecorder> clipRecorder;
|
| if (parentLayer && !RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
|
| ClipRect clipRectForFragment(ancestorBackgroundClipRect);
|
| - // A fixed-position object is repeated on every page, but if it is clipped
|
| - // by an ancestor layer then the repetitions are clipped out.
|
| - if (!isFixedPosObjectInPagedMedia)
|
| + // A fixed-position object is repeated on every page instead of paginated,
|
| + // so we should apply the original ancestor clip rect.
|
| + if (!isFixedPositionObjectInPagedMedia)
|
| clipRectForFragment.moveBy(fragment.paginationOffset);
|
| clipRectForFragment.intersect(fragment.backgroundRect);
|
| if (clipRectForFragment.isEmpty())
|
|
|