| Index: Source/core/rendering/RenderBox.cpp
|
| diff --git a/Source/core/rendering/RenderBox.cpp b/Source/core/rendering/RenderBox.cpp
|
| index 00fb3b2b4ca16f8c29a0b16a396659355378f8b8..58c16a9282c8d730bce122b7409f81007da13ee1 100644
|
| --- a/Source/core/rendering/RenderBox.cpp
|
| +++ b/Source/core/rendering/RenderBox.cpp
|
| @@ -1458,17 +1458,37 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
|
| return false;
|
| }
|
|
|
| -bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumulatedOffset)
|
| +bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumulatedOffset, const LayoutRect* visualOverflowRect)
|
| {
|
| if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseSelfOutline || paintInfo.phase == PaintPhaseMask)
|
| return false;
|
| -
|
| +
|
| bool isControlClip = hasControlClip();
|
| bool isOverflowClip = hasOverflowClip() && !layer()->isSelfPaintingLayer();
|
| -
|
| +
|
| if (!isControlClip && !isOverflowClip)
|
| return false;
|
| -
|
| +
|
| + if (visualOverflowRect && visualOverflowRect->isEmpty())
|
| + return false;
|
| +
|
| + LayoutRect clipRect = isControlClip ? controlClipRect(accumulatedOffset) : overflowClipRect(accumulatedOffset, paintInfo.renderRegion);
|
| + RoundedRect clipRRect(0, 0, 0, 0);
|
| + bool hasBorderRadius = style()->hasBorderRadius();
|
| + if (hasBorderRadius)
|
| + clipRRect = style()->getRoundedInnerBorderFor(LayoutRect(accumulatedOffset, size()));
|
| +
|
| + if (visualOverflowRect) {
|
| + LayoutRect conservativeClipRect = clipRect;
|
| + if (hasBorderRadius)
|
| + conservativeClipRect.intersect(clipRRect.enclosedRect());
|
| + conservativeClipRect.moveBy(-accumulatedOffset);
|
| + if (hasLayer())
|
| + conservativeClipRect.move(scrolledContentOffset());
|
| + if (conservativeClipRect.contains(*visualOverflowRect))
|
| + return false;
|
| + }
|
| +
|
| if (paintInfo.phase == PaintPhaseOutline)
|
| paintInfo.phase = PaintPhaseChildOutlines;
|
| else if (paintInfo.phase == PaintPhaseChildBlockBackground) {
|
| @@ -1476,11 +1496,10 @@ bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumu
|
| paintObject(paintInfo, accumulatedOffset);
|
| paintInfo.phase = PaintPhaseChildBlockBackgrounds;
|
| }
|
| - IntRect clipRect = pixelSnappedIntRect(isControlClip ? controlClipRect(accumulatedOffset) : overflowClipRect(accumulatedOffset, paintInfo.renderRegion));
|
| paintInfo.context->save();
|
| - if (style()->hasBorderRadius())
|
| - paintInfo.context->clipRoundedRect(style()->getRoundedInnerBorderFor(LayoutRect(accumulatedOffset, size())));
|
| - paintInfo.context->clip(clipRect);
|
| + if (hasBorderRadius)
|
| + paintInfo.context->clipRoundedRect(clipRRect);
|
| + paintInfo.context->clip(pixelSnappedIntRect(clipRect));
|
| return true;
|
| }
|
|
|
| @@ -4099,13 +4118,13 @@ void RenderBox::addVisualEffectOverflow()
|
|
|
| bool isFlipped = style()->isFlippedBlocksWritingMode();
|
| bool isHorizontal = isHorizontalWritingMode();
|
| -
|
| +
|
| LayoutRect borderBox = borderBoxRect();
|
| LayoutUnit overflowMinX = borderBox.x();
|
| LayoutUnit overflowMaxX = borderBox.maxX();
|
| LayoutUnit overflowMinY = borderBox.y();
|
| LayoutUnit overflowMaxY = borderBox.maxY();
|
| -
|
| +
|
| // Compute box-shadow overflow first.
|
| if (style()->boxShadow()) {
|
| LayoutUnit shadowLeft;
|
| @@ -4124,7 +4143,7 @@ void RenderBox::addVisualEffectOverflow()
|
| // Now compute border-image-outset overflow.
|
| if (style()->hasBorderImageOutsets()) {
|
| LayoutBoxExtent borderOutsets = style()->borderImageOutsets();
|
| -
|
| +
|
| // In flipped blocks writing modes, the physical sides are inverted. For example in vertical-rl, the right
|
| // border is at the lower x coordinate value.
|
| overflowMinX = min(overflowMinX, borderBox.x() - ((!isFlipped || isHorizontal) ? borderOutsets.left() : borderOutsets.right()));
|
| @@ -4134,7 +4153,8 @@ void RenderBox::addVisualEffectOverflow()
|
| }
|
|
|
| // Add in the final overflow with shadows and outsets combined.
|
| - addVisualOverflow(LayoutRect(overflowMinX, overflowMinY, overflowMaxX - overflowMinX, overflowMaxY - overflowMinY));
|
| + LayoutRect visualOverflowRect(overflowMinX, overflowMinY, overflowMaxX - overflowMinX, overflowMaxY - overflowMinY);
|
| + addVisualOverflow(visualOverflowRect, VisualOverflowNotClipped);
|
| }
|
|
|
| void RenderBox::addOverflowFromChild(RenderBox* child, const LayoutSize& delta)
|
| @@ -4146,18 +4166,23 @@ void RenderBox::addOverflowFromChild(RenderBox* child, const LayoutSize& delta)
|
| // Only propagate layout overflow from the child if the child isn't clipping its overflow. If it is, then
|
| // its overflow is internal to it, and we don't care about it. layoutOverflowRectForPropagation takes care of this
|
| // and just propagates the border box rect instead.
|
| - LayoutRect childLayoutOverflowRect = child->layoutOverflowRectForPropagation(style());
|
| - childLayoutOverflowRect.move(delta);
|
| - addLayoutOverflow(childLayoutOverflowRect);
|
| -
|
| + // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
|
| + if (child->style()->position() != FixedPosition) {
|
| + LayoutRect childLayoutOverflowRect = child->layoutOverflowRectForPropagation(style());
|
| + childLayoutOverflowRect.move(delta);
|
| + addLayoutOverflow(childLayoutOverflowRect);
|
| + }
|
| +
|
| // Add in visual overflow from the child. Even if the child clips its overflow, it may still
|
| - // have visual overflow of its own set from box shadows or reflections. It is unnecessary to propagate this
|
| - // overflow if we are clipping our own overflow.
|
| - if (child->hasSelfPaintingLayer() || hasOverflowClip())
|
| + // have visual overflow of its own set from box shadows or reflections.
|
| + if (child->hasSelfPaintingLayer())
|
| return;
|
| LayoutRect childVisualOverflowRect = child->visualOverflowRectForPropagation(style());
|
| childVisualOverflowRect.move(delta);
|
| - addVisualOverflow(childVisualOverflowRect);
|
| + VisualOverflowClipBehavior clipBehavior = VisualOverflowClippedByContentsClip;
|
| + if (child->isOutOfFlowPositioned())
|
| + clipBehavior = VisualOverflowNotClipped;
|
| + addVisualOverflow(childVisualOverflowRect, clipBehavior);
|
| }
|
|
|
| void RenderBox::addLayoutOverflow(const LayoutRect& rect)
|
| @@ -4210,15 +4235,18 @@ void RenderBox::addLayoutOverflow(const LayoutRect& rect)
|
| m_overflow->addLayoutOverflow(overflowRect);
|
| }
|
|
|
| -void RenderBox::addVisualOverflow(const LayoutRect& rect)
|
| +void RenderBox::addVisualOverflow(const LayoutRect& rect, VisualOverflowClipBehavior clipBehavior)
|
| {
|
| + if (clipBehavior == VisualOverflowClippedByContentsClip && hasOverflowClip())
|
| + return;
|
| +
|
| LayoutRect borderBox = borderBoxRect();
|
| if (borderBox.contains(rect) || rect.isEmpty())
|
| return;
|
| -
|
| +
|
| if (!m_overflow)
|
| m_overflow = adoptPtr(new RenderOverflow(clientBoxRect(), borderBox));
|
| -
|
| +
|
| m_overflow->addVisualOverflow(rect);
|
| }
|
|
|
| @@ -4226,12 +4254,12 @@ void RenderBox::clearLayoutOverflow()
|
| {
|
| if (!m_overflow)
|
| return;
|
| -
|
| +
|
| if (visualOverflowRect() == borderBoxRect()) {
|
| m_overflow.clear();
|
| return;
|
| }
|
| -
|
| +
|
| m_overflow->setLayoutOverflow(borderBoxRect());
|
| }
|
|
|
|
|