示例#1
0
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;
}
示例#3
0
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;
}
示例#4
0
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);
    }
}
示例#5
0
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);
    }
}
示例#7
0
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;
}
示例#8
0
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;
}