void PaintLayerClipper::calculateRectsWithGeometryMapper( const ClipRectsContext& context, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds, ClipRect& backgroundRect, ClipRect& foregroundRect, const LayoutPoint* offsetFromRoot) const { backgroundRect = applyOverflowClipToBackgroundRectWithGeometryMapper( context, clipRectWithGeometryMapper(context, false)); backgroundRect.move( context.subPixelAccumulation); // TODO(chrishtr): is this needed? backgroundRect.intersect(paintDirtyRect); foregroundRect.move( context.subPixelAccumulation); // TODO(chrishtr): is this needed? foregroundRect = clipRectWithGeometryMapper(context, true); foregroundRect.intersect(paintDirtyRect); LayoutPoint offset; if (offsetFromRoot) offset = *offsetFromRoot; else m_layer.convertToLayerCoords(context.rootLayer, offset); layerBounds = LayoutRect(offset, LayoutSize(m_layer.size())); #ifdef CHECK_CLIP_RECTS ClipRect testBackgroundRect, testForegroundRect; LayoutRect testLayerBounds; PaintLayerClipper(m_layer, false) .calculateRects(context, paintDirtyRect, testLayerBounds, testBackgroundRect, testForegroundRect); CHECK_RECTS_EQ(testBackgroundRect, backgroundRect); CHECK_RECTS_EQ(testForegroundRect, foregroundRect); CHECK_RECTS_EQ(testLayerBounds, layerBounds); #endif }
ClipRect RenderLayerClipper::backgroundClipRect(const ClipRectsContext& clipRectsContext) const { ASSERT(m_renderer.layer()->parent()); if (clipRectsContext.clipRectsType == CompositingClipRects) const_cast<RenderLayerClipper*>(this)->clearClipRectsIncludingDescendants(CompositingClipRects); ClipRects parentRects; // If we cross into a different pagination context, then we can't rely on the cache. // Just switch over to using TemporaryClipRects. if (clipRectsContext.clipRectsType != TemporaryClipRects && m_renderer.layer()->parent()->enclosingPaginationLayer() != m_renderer.layer()->enclosingPaginationLayer()) { ClipRectsContext tempContext(clipRectsContext); tempContext.clipRectsType = TemporaryClipRects; parentClipRects(tempContext, parentRects); } else { parentClipRects(clipRectsContext, parentRects); } ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, m_renderer.style()->position()); RenderView* view = m_renderer.view(); ASSERT(view); // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite. if (parentRects.fixed() && clipRectsContext.rootLayer->renderer() == view && backgroundClipRect != PaintInfo::infiniteRect()) backgroundClipRect.move(view->frameView()->scrollOffsetForFixedPosition()); return backgroundClipRect; }
ClipRect PaintLayerClipper::backgroundClipRect( const ClipRectsContext& context) const { if (m_geometryMapper) { ClipRect backgroundClipRect = clipRectWithGeometryMapper(context, false); #ifdef CHECK_CLIP_RECTS ClipRect testBackgroundClipRect = PaintLayerClipper(m_layer, false).backgroundClipRect(context); CHECK_RECTS_EQ(testBackgroundClipRect, backgroundClipRect); #endif return backgroundClipRect; } DCHECK(m_layer.parent()); LayoutView* layoutView = m_layer.layoutObject()->view(); DCHECK(layoutView); RefPtr<ClipRects> parentClipRects = ClipRects::create(); if (&m_layer == context.rootLayer) parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); else m_layer.parent()->clipper().getOrCalculateClipRects(context, *parentClipRects); ClipRect result = backgroundClipRectForPosition( *parentClipRects, m_layer.layoutObject()->styleRef().position()); // Note: infinite clipRects should not be scrolled here, otherwise they will // accidentally no longer be considered infinite. if (parentClipRects->fixed() && context.rootLayer->layoutObject() == layoutView && result != LayoutRect(LayoutRect::infiniteIntRect())) result.move(LayoutSize(layoutView->frameView()->scrollOffset())); return result; }
void RenderLayerClipper::calculateRects(const ClipRectsContext& clipRectsContext, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds, ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot) const { if (clipRectsContext.rootLayer != m_renderer->layer() && m_renderer->layer()->parent()) { backgroundRect = backgroundClipRect(clipRectsContext); backgroundRect.move(roundedIntSize(clipRectsContext.subPixelAccumulation)); backgroundRect.intersect(paintDirtyRect); } else { backgroundRect = paintDirtyRect; } foregroundRect = backgroundRect; outlineRect = backgroundRect; LayoutPoint offset; if (offsetFromRoot) offset = *offsetFromRoot; else m_renderer->layer()->convertToLayerCoords(clipRectsContext.rootLayer, offset); layerBounds = LayoutRect(offset, m_renderer->layer()->size()); // Update the clip rects that will be passed to child layers. if (m_renderer->hasOverflowClip()) { // This layer establishes a clip of some kind. if (m_renderer->layer() != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip) { foregroundRect.intersect(toRenderBox(m_renderer)->overflowClipRect(offset, clipRectsContext.overlayScrollbarSizeRelevancy)); if (m_renderer->style()->hasBorderRadius()) foregroundRect.setHasRadius(true); } // If we establish an overflow clip at all, then go ahead and make sure our background // rect is intersected with our layer's bounds including our visual overflow, // since any visual overflow like box-shadow or border-outset is not clipped by overflow:auto/hidden. if (toRenderBox(m_renderer)->hasVisualOverflow()) { // FIXME: Perhaps we should be propagating the borderbox as the clip rect for children, even though // we may need to inflate our clip specifically for shadows or outsets. // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the // individual region boxes as overflow. LayoutRect layerBoundsWithVisualOverflow = toRenderBox(m_renderer)->visualOverflowRect(); toRenderBox(m_renderer)->flipForWritingMode(layerBoundsWithVisualOverflow); // Layers are in physical coordinates, so the overflow has to be flipped. layerBoundsWithVisualOverflow.moveBy(offset); if (m_renderer->layer() != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip) backgroundRect.intersect(layerBoundsWithVisualOverflow); } else { LayoutRect bounds = toRenderBox(m_renderer)->borderBoxRect(); bounds.moveBy(offset); if (m_renderer->layer() != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip) backgroundRect.intersect(bounds); } } // CSS clip (different than clipping due to overflow) can clip to any box, even if it falls outside of the border box. if (m_renderer->hasClip()) { // Clip applies to *us* as well, so go ahead and update the damageRect. LayoutRect newPosClip = toRenderBox(m_renderer)->clipRect(offset); backgroundRect.intersect(newPosClip); foregroundRect.intersect(newPosClip); outlineRect.intersect(newPosClip); } }
void PaintLayerClipper::calculateRects(const ClipRectsContext& context, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds, ClipRect& backgroundRect, ClipRect& foregroundRect, const LayoutPoint* offsetFromRoot) const { bool isClippingRoot = m_layoutObject.layer() == context.rootLayer; if (!isClippingRoot && m_layoutObject.layer()->parent()) { backgroundRect = backgroundClipRect(context); backgroundRect.move(context.subPixelAccumulation); backgroundRect.intersect(paintDirtyRect); } else { backgroundRect = paintDirtyRect; } foregroundRect = backgroundRect; LayoutPoint offset; if (offsetFromRoot) offset = *offsetFromRoot; else m_layoutObject.layer()->convertToLayerCoords(context.rootLayer, offset); layerBounds = LayoutRect(offset, LayoutSize(m_layoutObject.layer()->size())); // Update the clip rects that will be passed to child layers. if (m_layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) { foregroundRect.intersect(toLayoutBox(m_layoutObject).overflowClipRect(offset, context.scrollbarRelevancy)); if (m_layoutObject.style()->hasBorderRadius()) foregroundRect.setHasRadius(true); // FIXME: Does not do the right thing with columns yet, since we don't yet factor in the // individual column boxes as overflow. // The LayoutView is special since its overflow clipping rect may be larger than its box rect (crbug.com/492871). LayoutRect layerBoundsWithVisualOverflow = m_layoutObject.isLayoutView() ? toLayoutView(m_layoutObject).viewRect() : toLayoutBox(m_layoutObject).visualOverflowRect(); toLayoutBox(m_layoutObject).flipForWritingMode(layerBoundsWithVisualOverflow); // PaintLayer are in physical coordinates, so the overflow has to be flipped. layerBoundsWithVisualOverflow.moveBy(offset); backgroundRect.intersect(layerBoundsWithVisualOverflow); } // CSS clip (different than clipping due to overflow) can clip to any box, even if it falls outside of the border box. if (m_layoutObject.hasClip()) { // Clip applies to *us* as well, so go ahead and update the damageRect. LayoutRect newPosClip = toLayoutBox(m_layoutObject).clipRect(offset); backgroundRect.intersect(newPosClip); backgroundRect.setIsClippedByClipCss(); foregroundRect.intersect(newPosClip); foregroundRect.setIsClippedByClipCss(); } }
void RenderLayerClipper::calculateRects(const ClipRectsContext& context, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds, ClipRect& backgroundRect, const LayoutPoint* offsetFromRoot) const { bool isClippingRoot = m_renderer.layer() == context.rootLayer; if (!isClippingRoot && m_renderer.layer()->parent()) { backgroundRect = backgroundClipRect(context); backgroundRect.move(roundedIntSize(context.subPixelAccumulation)); backgroundRect.intersect(paintDirtyRect); } else { backgroundRect = paintDirtyRect; } LayoutPoint offset; if (offsetFromRoot) offset = *offsetFromRoot; else m_renderer.layer()->convertToLayerCoords(context.rootLayer, offset); layerBounds = LayoutRect(offset, m_renderer.layer()->size()); // Update the clip rects that will be passed to child layers. if (m_renderer.hasOverflowClip()) { // If we establish an overflow clip at all, then go ahead and make sure our background // rect is intersected with our layer's bounds including our visual overflow, // since any visual overflow like box-shadow or border-outset is not clipped by overflow:auto/hidden. if (m_renderer.hasVisualOverflow()) { // FIXME: Perhaps we should be propagating the borderbox as the clip rect for children, even though // we may need to inflate our clip specifically for shadows or outsets. // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the // individual region boxes as overflow. LayoutRect layerBoundsWithVisualOverflow = m_renderer.visualOverflowRect(); layerBoundsWithVisualOverflow.moveBy(offset); backgroundRect.intersect(layerBoundsWithVisualOverflow); } else { LayoutRect bounds = m_renderer.borderBoxRect(); bounds.moveBy(offset); backgroundRect.intersect(bounds); } } // CSS clip (different than clipping due to overflow) can clip to any box, even if it falls outside of the border box. if (m_renderer.hasClip()) { // Clip applies to *us* as well, so go ahead and update the damageRect. LayoutRect newPosClip = m_renderer.clipRect(offset); backgroundRect.intersect(newPosClip); } }
ClipRect PaintLayerClipper::backgroundClipRect(const ClipRectsContext& context) const { ASSERT(m_layoutObject.layer()->parent()); ASSERT(m_layoutObject.view()); RefPtr<ClipRects> parentClipRects = ClipRects::create(); if (m_layoutObject.layer() == context.rootLayer) parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); else m_layoutObject.layer()->parent()->clipper().getOrCalculateClipRects(context, *parentClipRects); ClipRect result = backgroundClipRectForPosition(*parentClipRects, m_layoutObject.style()->position()); // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite. if (parentClipRects->fixed() && context.rootLayer->layoutObject() == m_layoutObject.view() && result != LayoutRect(LayoutRect::infiniteIntRect())) result.move(toIntSize(m_layoutObject.view()->frameView()->scrollPosition())); return result; }
ClipRect RenderLayerClipper::backgroundClipRect(const ClipRectsContext& context) const { ASSERT(m_renderer.layer()->parent()); ASSERT(m_renderer.view()); ClipRects parentClipRects; if (m_renderer.layer() == context.rootLayer) parentClipRects.reset(PaintInfo::infiniteRect()); else m_renderer.layer()->parent()->clipper().getOrCalculateClipRects(context, parentClipRects); ClipRect result = backgroundClipRectForPosition(parentClipRects, m_renderer.style()->position()); // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite. if (parentClipRects.fixed() && context.rootLayer->renderer() == m_renderer.view() && result != PaintInfo::infiniteRect()) result.move(m_renderer.view()->frameView()->scrollOffsetForFixedPosition()); return result; }