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; }
void PaintLayerClipper::calculateClipRects(const ClipRectsContext& context, ClipRects& clipRects) const { bool rootLayerScrolls = m_layoutObject.document().settings() && m_layoutObject.document().settings()->rootLayerScrolls(); if (!m_layoutObject.layer()->parent() && !rootLayerScrolls) { // The root layer's clip rect is always infinite. clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); return; } bool isClippingRoot = m_layoutObject.layer() == context.rootLayer; // For transformed layers, the root layer was shifted to be us, so there is no need to // examine the parent. We want to cache clip rects with us as the root. PaintLayer* parentLayer = !isClippingRoot ? m_layoutObject.layer()->parent() : 0; // Ensure that our parent's clip has been calculated so that we can examine the values. if (parentLayer) { // FIXME: Why don't we just call getClipRects here? if (context.usesCache() && parentLayer->clipper().cachedClipRects(context)) { clipRects = *parentLayer->clipper().cachedClipRects(context); } else { parentLayer->clipper().calculateClipRects(context, clipRects); } } else { clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); } adjustClipRectsForChildren(m_layoutObject, clipRects); if ((m_layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) || m_layoutObject.hasClip()) { // This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across // some transformed layer boundary, for example, in the PaintLayerCompositor overlapMap, where // clipRects are needed in view space. applyClipRects(context, m_layoutObject, roundedLayoutPoint(m_layoutObject.localToContainerPoint(FloatPoint(), context.rootLayer->layoutObject())), clipRects); } }
static void adjustClipRectsForChildren(const RenderObject& renderer, ClipRects& clipRects) { EPosition position = renderer.style()->position(); if (position == RelativePosition) { clipRects.setPosClipRect(clipRects.overflowClipRect()); } else if (position == AbsolutePosition) { clipRects.setOverflowClipRect(clipRects.posClipRect()); } }
static ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPosition position) { if (position == FixedPosition) return parentRects.fixedClipRect(); if (position == AbsolutePosition) return parentRects.posClipRect(); return parentRects.overflowClipRect(); }
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); return backgroundClipRectForPosition(parentClipRects, m_renderer.style()->position()); }
ClipRect RenderLayerClipper::backgroundClipRect(const ClipRectsContext& context) const { ASSERT(m_renderer.layer()->parent()); ClipRects parentClipRects; if (m_renderer.layer() == context.rootLayer) parentClipRects.reset(PaintInfo::infiniteRect()); else m_renderer.layer()->parent()->clipper().getOrCalculateClipRects(context, parentClipRects); if (m_renderer.style()->position() == AbsolutePosition) return parentClipRects.posClipRect(); return parentClipRects.overflowClipRect(); }
static void adjustClipRectsForChildren(const LayoutObject& layoutObject, ClipRects& clipRects) { EPosition position = layoutObject.style()->position(); // A fixed object is essentially the root of its containing block hierarchy, so when // we encounter such an object, we reset our clip rects to the fixedClipRect. if (position == FixedPosition) { clipRects.setPosClipRect(clipRects.fixedClipRect()); clipRects.setOverflowClipRect(clipRects.fixedClipRect()); clipRects.setFixed(true); } else if (position == RelativePosition) { clipRects.setPosClipRect(clipRects.overflowClipRect()); } else if (position == AbsolutePosition) { clipRects.setOverflowClipRect(clipRects.posClipRect()); } }
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; }
void PaintLayerClipper::calculateClipRects(const ClipRectsContext& context, ClipRects& clipRects) const { const LayoutBoxModelObject& layoutObject = *m_layer.layoutObject(); if (!m_layer.parent() && !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { // The root layer's clip rect is always infinite. clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); return; } bool isClippingRoot = &m_layer == context.rootLayer; // For transformed layers, the root layer was shifted to be us, so there is no // need to examine the parent. We want to cache clip rects with us as the // root. PaintLayer* parentLayer = !isClippingRoot ? m_layer.parent() : nullptr; // Ensure that our parent's clip has been calculated so that we can examine // the values. if (parentLayer) { parentLayer->clipper().getOrCalculateClipRects(context, clipRects); } else { clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); } adjustClipRectsForChildren(layoutObject, clipRects); if (shouldClipOverflow(context) || layoutObject.hasClip() || (layoutObject.isSVGRoot() && toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip())) { // This offset cannot use convertToLayerCoords, because sometimes our // rootLayer may be across some transformed layer boundary, for example, in // the PaintLayerCompositor overlapMap, where clipRects are needed in view // space. applyClipRects(context, layoutObject, roundedLayoutPoint(layoutObject.localToAncestorPoint( FloatPoint(), context.rootLayer->layoutObject())), clipRects); } }
void RenderLayerClipper::calculateClipRects(const ClipRectsContext& context, ClipRects& clipRects) const { if (!m_renderer.layer()->parent()) { // The root layer's clip rect is always infinite. clipRects.reset(PaintInfo::infiniteRect()); return; } bool isClippingRoot = m_renderer.layer() == context.rootLayer; // For transformed layers, the root layer was shifted to be us, so there is no need to // examine the parent. We want to cache clip rects with us as the root. RenderLayer* parentLayer = !isClippingRoot ? m_renderer.layer()->parent() : 0; // Ensure that our parent's clip has been calculated so that we can examine the values. if (parentLayer) { // FIXME: Why don't we just call getClipRects here? if (context.usesCache() && parentLayer->clipper().cachedClipRects(context)) { clipRects = *parentLayer->clipper().cachedClipRects(context); } else { parentLayer->clipper().calculateClipRects(context, clipRects); } } else { clipRects.reset(PaintInfo::infiniteRect()); } adjustClipRectsForChildren(m_renderer, clipRects); // FIXME: This logic looks wrong. We'll apply overflow clip rects even if we were told to IgnoreOverflowClip if m_renderer.hasClip(). if ((m_renderer.hasOverflowClip() && (context.respectOverflowClip == RespectOverflowClip || !isClippingRoot)) || m_renderer.hasClip()) { // This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across // some transformed layer boundary, for example, in the RenderLayerCompositor overlapMap, where // clipRects are needed in view space. applyClipRects(context, m_renderer, roundedLayoutPoint(m_renderer.localToContainerPoint(FloatPoint(), context.rootLayer->renderer())), clipRects); } }
static void applyClipRects(const ClipRectsContext& context, RenderObject& renderer, LayoutPoint offset, ClipRects& clipRects) { ASSERT(renderer.hasOverflowClip() || renderer.hasClip()); if (renderer.hasOverflowClip()) { ClipRect newOverflowClip = toRenderBox(renderer).overflowClipRect(offset); newOverflowClip.setHasRadius(renderer.style()->hasBorderRadius()); clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect())); if (renderer.isPositioned()) clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect())); } if (renderer.hasClip()) { LayoutRect newClip = toRenderBox(renderer).clipRect(offset); clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect())); clipRects.setOverflowClipRect(intersection(newClip, clipRects.overflowClipRect())); } }
void RenderLayerClipper::parentClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const { // The root is not clipped. if (isClippingRootForContext(clipRectsContext)) { clipRects.reset(PaintInfo::infiniteRect()); return; } ASSERT(m_renderer.layer()->parent()); RenderLayerClipper& parentClipper = m_renderer.layer()->parent()->clipper(); if (clipRectsContext.clipRectsType == TemporaryClipRects) { parentClipper.calculateClipRects(clipRectsContext, clipRects); return; } parentClipper.updateClipRects(clipRectsContext); clipRects = *parentClipper.clipRects(clipRectsContext); }
void RenderLayerClipper::calculateClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const { if (!m_renderer->layer()->parent()) { // The root layer's clip rect is always infinite. clipRects.reset(PaintInfo::infiniteRect()); return; } ClipRectsType clipRectsType = clipRectsContext.clipRectsType; bool useCached = clipRectsType != TemporaryClipRects; // For transformed layers, the root layer was shifted to be us, so there is no need to // examine the parent. We want to cache clip rects with us as the root. RenderLayer* parentLayer = clipRectsContext.rootLayer != m_renderer->layer() ? m_renderer->layer()->parent() : 0; // Ensure that our parent's clip has been calculated so that we can examine the values. if (parentLayer) { if (useCached && parentLayer->clipper().clipRects(clipRectsContext)) { clipRects = *parentLayer->clipper().clipRects(clipRectsContext); } else { ClipRectsContext parentContext(clipRectsContext); parentContext.overlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize; // FIXME: why? parentLayer->clipper().calculateClipRects(parentContext, clipRects); } } else { clipRects.reset(PaintInfo::infiniteRect()); } // A fixed object is essentially the root of its containing block hierarchy, so when // we encounter such an object, we reset our clip rects to the fixedClipRect. if (m_renderer->style()->position() == FixedPosition) { clipRects.setPosClipRect(clipRects.fixedClipRect()); clipRects.setOverflowClipRect(clipRects.fixedClipRect()); clipRects.setFixed(true); } else if (m_renderer->style()->hasInFlowPosition()) { clipRects.setPosClipRect(clipRects.overflowClipRect()); } else if (m_renderer->style()->position() == AbsolutePosition) { clipRects.setOverflowClipRect(clipRects.posClipRect()); } // Update the clip rects that will be passed to child layers. if ((m_renderer->hasOverflowClip() && (clipRectsContext.respectOverflowClip == RespectOverflowClip || m_renderer->layer() != clipRectsContext.rootLayer)) || m_renderer->hasClip()) { // This layer establishes a clip of some kind. // This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across // some transformed layer boundary, for example, in the RenderLayerCompositor overlapMap, where // clipRects are needed in view space. LayoutPoint offset; offset = roundedLayoutPoint(m_renderer->localToContainerPoint(FloatPoint(), clipRectsContext.rootLayer->renderer())); RenderView* view = m_renderer->view(); ASSERT(view); if (view && clipRects.fixed() && clipRectsContext.rootLayer->renderer() == view) { offset -= view->frameView()->scrollOffsetForFixedPosition(); } if (m_renderer->hasOverflowClip()) { ClipRect newOverflowClip = toRenderBox(m_renderer)->overflowClipRect(offset, clipRectsContext.region, clipRectsContext.overlayScrollbarSizeRelevancy); if (m_renderer->style()->hasBorderRadius()) newOverflowClip.setHasRadius(true); clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect())); if (m_renderer->isPositioned()) clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect())); } if (m_renderer->hasClip()) { LayoutRect newPosClip = toRenderBox(m_renderer)->clipRect(offset, clipRectsContext.region); clipRects.setPosClipRect(intersection(newPosClip, clipRects.posClipRect())); clipRects.setOverflowClipRect(intersection(newPosClip, clipRects.overflowClipRect())); clipRects.setFixedClipRect(intersection(newPosClip, clipRects.fixedClipRect())); } } }
static void applyClipRects(const ClipRectsContext& context, RenderObject& renderer, LayoutPoint offset, ClipRects& clipRects) { ASSERT(renderer.hasOverflowClip() || renderer.hasClip()); RenderView* view = renderer.view(); ASSERT(view); if (clipRects.fixed() && context.rootLayer->renderer() == view) offset -= view->frameView()->scrollOffsetForFixedPosition(); if (renderer.hasOverflowClip()) { ClipRect newOverflowClip = toRenderBox(renderer).overflowClipRect(offset, context.scrollbarRelevancy); newOverflowClip.setHasRadius(renderer.style()->hasBorderRadius()); clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect())); if (renderer.isPositioned()) clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect())); } if (renderer.hasClip()) { LayoutRect newClip = toRenderBox(renderer).clipRect(offset); clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect())); clipRects.setOverflowClipRect(intersection(newClip, clipRects.overflowClipRect())); clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect())); } }
static void applyClipRects(const ClipRectsContext& context, const LayoutBoxModelObject& layoutObject, LayoutPoint offset, ClipRects& clipRects) { DCHECK(layoutObject.hasClipRelatedProperty() || (layoutObject.isSVGRoot() && toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip())); LayoutView* view = layoutObject.view(); DCHECK(view); if (clipRects.fixed() && context.rootLayer->layoutObject() == view) offset -= LayoutSize(view->frameView()->scrollOffset()); if (layoutObject.hasOverflowClip() || (layoutObject.isSVGRoot() && toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip()) || (layoutObject.styleRef().containsPaint() && layoutObject.isBox())) { ClipRect newOverflowClip = toLayoutBox(layoutObject) .overflowClipRect(offset, context.overlayScrollbarClipBehavior); newOverflowClip.setHasRadius(layoutObject.styleRef().hasBorderRadius()); clipRects.setOverflowClipRect( intersection(newOverflowClip, clipRects.overflowClipRect())); if (layoutObject.isPositioned()) clipRects.setPosClipRect( intersection(newOverflowClip, clipRects.posClipRect())); if (layoutObject.isLayoutView()) clipRects.setFixedClipRect( intersection(newOverflowClip, clipRects.fixedClipRect())); if (layoutObject.styleRef().containsPaint()) { clipRects.setPosClipRect( intersection(newOverflowClip, clipRects.posClipRect())); clipRects.setFixedClipRect( intersection(newOverflowClip, clipRects.fixedClipRect())); } } if (layoutObject.hasClip()) { LayoutRect newClip = toLayoutBox(layoutObject).clipRect(offset); clipRects.setPosClipRect( intersection(newClip, clipRects.posClipRect()).setIsClippedByClipCss()); clipRects.setOverflowClipRect( intersection(newClip, clipRects.overflowClipRect()) .setIsClippedByClipCss()); clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect()) .setIsClippedByClipCss()); } }
void RenderLayerClipper::calculateClipRects(const ClipRectsContext& context, ClipRects& clipRects) const { if (!m_renderer.layer()->parent()) { // The root layer's clip rect is always infinite. clipRects.reset(PaintInfo::infiniteRect()); return; } bool isClippingRoot = m_renderer.layer() == context.rootLayer; // For transformed layers, the root layer was shifted to be us, so there is no need to // examine the parent. We want to cache clip rects with us as the root. RenderLayer* parentLayer = !isClippingRoot ? m_renderer.layer()->parent() : 0; // Ensure that our parent's clip has been calculated so that we can examine the values. if (parentLayer) { // FIXME: Why don't we just call getClipRects here? if (context.usesCache() && parentLayer->clipper().cachedClipRects(context)) { clipRects = *parentLayer->clipper().cachedClipRects(context); } else { parentLayer->clipper().calculateClipRects(context, clipRects); } } else { clipRects.reset(PaintInfo::infiniteRect()); } if (m_renderer.style()->position() == AbsolutePosition) { clipRects.setOverflowClipRect(clipRects.posClipRect()); } // This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across // some transformed layer boundary, for example, in the RenderLayerCompositor overlapMap, where // clipRects are needed in view space. LayoutPoint offset = roundedLayoutPoint(m_renderer.localToContainerPoint(FloatPoint(), context.rootLayer->renderer())); if (m_renderer.hasOverflowClip()) { ClipRect newOverflowClip = m_renderer.overflowClipRect(offset); newOverflowClip.setHasRadius(m_renderer.style()->hasBorderRadius()); clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect())); if (m_renderer.isPositioned()) clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect())); } if (m_renderer.hasClip()) { LayoutRect newClip = m_renderer.clipRect(offset); clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect())); clipRects.setOverflowClipRect(intersection(newClip, clipRects.overflowClipRect())); } }
static void applyClipRects(const ClipRectsContext& context, const LayoutObject& layoutObject, LayoutPoint offset, ClipRects& clipRects) { ASSERT(layoutObject.hasOverflowClip() || layoutObject.hasClip()); LayoutView* view = layoutObject.view(); ASSERT(view); if (clipRects.fixed() && context.rootLayer->layoutObject() == view) offset -= toIntSize(view->frameView()->scrollPosition()); if (layoutObject.hasOverflowClip()) { ClipRect newOverflowClip = toLayoutBox(layoutObject).overflowClipRect(offset, context.scrollbarRelevancy); newOverflowClip.setHasRadius(layoutObject.style()->hasBorderRadius()); clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect())); if (layoutObject.isPositioned()) clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect())); if (layoutObject.isLayoutView()) clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.fixedClipRect())); } if (layoutObject.hasClip()) { LayoutRect newClip = toLayoutBox(layoutObject).clipRect(offset); clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect()).setIsClippedByClipCss()); clipRects.setOverflowClipRect(intersection(newClip, clipRects.overflowClipRect()).setIsClippedByClipCss()); clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect()).setIsClippedByClipCss()); } }