Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Unified Diff: third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp

Issue 2605333002: [SPInvalidation] Fix fixed-position printing (Closed)
Patch Set: Fix scrolled Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..ef264c495233ec02a464fe49399e6736fbc685c6 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -412,18 +412,23 @@ PaintResult PaintLayerPainter::paintLayerContents(
ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects)
? UncachedClipRects
: PaintingClipRects;
+ bool isFixedPositionObjectInPagedMedia =
+ fragmentPolicy != ForceSingleFragment &&
+ this->isFixedPositionObjectInPagedMedia();
// TODO(trchen): We haven't decided how to handle visual fragmentation with
// SPv2. Related thread
// https://groups.google.com/a/chromium.org/forum/#!topic/graphics-dev/81XuWFf-mxM
if (fragmentPolicy == ForceSingleFragment ||
+ isFixedPositionObjectInPagedMedia ||
RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
m_paintLayer.appendSingleFragmentIgnoringPagination(
layerFragments, localPaintingInfo.rootLayer,
localPaintingInfo.paintDirtyRect, cacheSlot,
IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot,
localPaintingInfo.subPixelAccumulation);
- } else if (!collectPaintFragmentsForPaginatedFixedPosition(
- paintingInfo, layerFragments)) {
+ if (isFixedPositionObjectInPagedMedia)
+ repeatFixedPositionObjectInPages(paintingInfo, layerFragments);
chrishtr 2016/12/30 00:10:50 It's only possible in single-fragment mode?
Xianzhu 2016/12/30 00:52:41 Now isFixedPositionObjectInPageMedia and single-fr
+ } else {
m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer,
localPaintingInfo.paintDirtyRect, cacheSlot,
IgnoreOverlayScrollbarSize,
@@ -586,40 +591,43 @@ 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
+void PaintLayerPainter::repeatFixedPositionObjectInPages(
+ const PaintLayerPaintingInfo& paintingInfo,
+ PaintLayerFragments& layerFragments) {
+ DCHECK(isFixedPositionObjectInPagedMedia());
+ DCHECK_EQ(1u, layerFragments.size());
- // "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[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];
chrishtr 2017/01/03 18:25:09 What guarantees that |layerFragments| has exactly
chrishtr 2017/01/03 18:53:10 oh I see now, nm.
+ fragment.paginationOffset += pageOffset;
+ fragment.layerBounds.moveBy(pageOffset);
chrishtr 2016/12/30 00:10:50 This didn't used to get set in the transformed pat
Xianzhu 2016/12/30 00:52:41 No. layerBounds and foregroundRect of these fragme
chrishtr 2017/01/03 18:25:09 I'm not sure what you mean. layerBounds is used in
chrishtr 2017/01/03 18:53:10 Right ok, now I see.
layerFragments.append(fragment);
- paginationOffset += LayoutPoint(LayoutUnit(), view->pageLogicalHeight());
}
- return true;
}
PaintResult PaintLayerPainter::paintLayerWithTransform(
@@ -637,48 +645,42 @@ 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;
- layerFragments.append(fragment);
- }
+ 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;
+ layerFragments.append(fragment);
+ if (isFixedPositionObjectInPagedMedia)
+ repeatFixedPositionObjectInPages(paintingInfo, layerFragments);
+ } 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, 0,
+ paintingInfo.subPixelAccumulation, &transformedExtent);
}
Optional<DisplayItemCacheSkipper> cacheSkipper;
@@ -707,9 +709,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())

Powered by Google App Engine
This is Rietveld 408576698