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

Unified Diff: Source/core/rendering/RenderBox.cpp

Issue 16402019: Remove clips where we can show that they are unnecessary. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: add TestExpectations for layout test changes due to crbug.com/249478 Created 7 years, 6 months 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: 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());
}

Powered by Google App Engine
This is Rietveld 408576698