- Revision
- 174986
- Author
- [email protected]
- Date
- 2014-10-21 10:32:09 -0700 (Tue, 21 Oct 2014)
Log Message
REGRESSION: Google Search (mobile) video thumbnails are too large.
https://bugs.webkit.org/show_bug.cgi?id=137895
Reviewed by Simon Fraser.
This patch fixes layer clipping when an ancestor layer has border-radius clipping.
In cases, where the current layer has non-radius cliprect, while an ancestor layer
has border-radius clipping, we only use the border-radius rect to clip.
Source/WebCore:
Test: fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent.html
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::clipToRect):
(WebCore::RenderLayer::restoreClip):
(WebCore::RenderLayer::collectFragments):
(WebCore::RenderLayer::calculateClipRects):
* rendering/RenderLayer.h:
(WebCore::ClipRect::ClipRect):
(WebCore::ClipRect::effectedByRadius):
(WebCore::ClipRect::setEffectedByRadius):
(WebCore::ClipRect::operator==):
(WebCore::ClipRect::operator!=):
(WebCore::ClipRect::intersect):
(WebCore::ClipRect::hasRadius): Deleted.
(WebCore::ClipRect::setHasRadius): Deleted.
LayoutTests:
* fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent-expected.html: Added.
* fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (174985 => 174986)
--- trunk/LayoutTests/ChangeLog 2014-10-21 17:19:49 UTC (rev 174985)
+++ trunk/LayoutTests/ChangeLog 2014-10-21 17:32:09 UTC (rev 174986)
@@ -1,3 +1,18 @@
+2014-10-21 Zalan Bujtas <[email protected]>
+
+ REGRESSION: Google Search (mobile) video thumbnails are too large.
+ https://bugs.webkit.org/show_bug.cgi?id=137895
+
+ Reviewed by Simon Fraser.
+
+ This patch fixes layer clipping when an ancestor layer has border-radius clipping.
+
+ In cases, where the current layer has non-radius cliprect, while an ancestor layer
+ has border-radius clipping, we only use the border-radius rect to clip.
+
+ * fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent-expected.html: Added.
+ * fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent.html: Added.
+
2014-10-21 Jer Noble <[email protected]>
REGRESSION (r170808): Volume slider in built-in media controls only changes volume when thumb is released, not while dragging
Added: trunk/LayoutTests/fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent-expected.html (0 => 174986)
--- trunk/LayoutTests/fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent-expected.html (rev 0)
+++ trunk/LayoutTests/fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent-expected.html 2014-10-21 17:32:09 UTC (rev 174986)
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that parent clipping is applied properly when ancestor border-radius is present.</title>
+<style>
+ .container {
+ overflow: hidden;
+ border-radius: 20px 0px 0px 0px;
+ height: 10px;
+ width: 10px;
+ }
+
+ .content {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+ }
+</style>
+</head>
+<body>
+<div class=container>
+ <div class=content></div>
+</div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent.html (0 => 174986)
--- trunk/LayoutTests/fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent.html (rev 0)
+++ trunk/LayoutTests/fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent.html 2014-10-21 17:32:09 UTC (rev 174986)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that parent clipping is applied properly when ancestor border-radius is present.</title>
+<style>
+ .outer {
+ overflow: hidden;
+ border-radius: 20px 0px 0px 0px;
+ }
+
+ .inner {
+ overflow: hidden;
+ position: relative;
+ height: 10px;
+ width: 10px;
+ }
+
+ .content {
+ width: 100px;
+ height: 100px;
+ background-color: red;
+ }
+</style>
+</head>
+<body>
+<div class=outer>
+ <div class=inner>
+ <div class=content></div>
+ </div>
+</div>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (174985 => 174986)
--- trunk/Source/WebCore/ChangeLog 2014-10-21 17:19:49 UTC (rev 174985)
+++ trunk/Source/WebCore/ChangeLog 2014-10-21 17:32:09 UTC (rev 174986)
@@ -1,3 +1,32 @@
+2014-10-21 Zalan Bujtas <[email protected]>
+
+ REGRESSION: Google Search (mobile) video thumbnails are too large.
+ https://bugs.webkit.org/show_bug.cgi?id=137895
+
+ Reviewed by Simon Fraser.
+
+ This patch fixes layer clipping when an ancestor layer has border-radius clipping.
+
+ In cases, where the current layer has non-radius cliprect, while an ancestor layer
+ has border-radius clipping, we only use the border-radius rect to clip.
+
+ Test: fast/clip/overflow-hidden-with-border-radius-overflow-clipping-parent.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::clipToRect):
+ (WebCore::RenderLayer::restoreClip):
+ (WebCore::RenderLayer::collectFragments):
+ (WebCore::RenderLayer::calculateClipRects):
+ * rendering/RenderLayer.h:
+ (WebCore::ClipRect::ClipRect):
+ (WebCore::ClipRect::effectedByRadius):
+ (WebCore::ClipRect::setEffectedByRadius):
+ (WebCore::ClipRect::operator==):
+ (WebCore::ClipRect::operator!=):
+ (WebCore::ClipRect::intersect):
+ (WebCore::ClipRect::hasRadius): Deleted.
+ (WebCore::ClipRect::setHasRadius): Deleted.
+
2014-10-20 Michael Saboff <[email protected]>
Don't create cached functions for HTMLDocument.write*()
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (174985 => 174986)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2014-10-21 17:19:49 UTC (rev 174985)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2014-10-21 17:32:09 UTC (rev 174986)
@@ -3664,10 +3664,19 @@
void RenderLayer::clipToRect(const LayerPaintingInfo& paintingInfo, GraphicsContext* context, const ClipRect& clipRect, BorderRadiusClippingRule rule)
{
+ bool needsClipping = clipRect.rect() != paintingInfo.paintDirtyRect;
+ if (needsClipping || clipRect.affectedByRadius())
+ context->save();
+
float deviceScaleFactor = renderer().document().deviceScaleFactor();
- if (clipRect.hasRadius()) {
- context->save();
-
+ bool layerHasBorderRadius = renderer().style().hasBorderRadius();
+ if (needsClipping && !layerHasBorderRadius) {
+ LayoutRect adjustedClipRect = clipRect.rect();
+ adjustedClipRect.move(paintingInfo.subpixelAccumulation);
+ context->clip(snapRectToDevicePixels(adjustedClipRect, deviceScaleFactor));
+ }
+
+ if (clipRect.affectedByRadius()) {
// If the clip rect has been tainted by a border radius, then we have to walk up our layer chain applying the clips from
// any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our
// containing block chain so we check that also.
@@ -3681,17 +3690,12 @@
if (layer == paintingInfo.rootLayer)
break;
}
- } else if (clipRect.rect() != paintingInfo.paintDirtyRect) {
- context->save();
- LayoutRect adjustedClipRect = clipRect.rect();
- adjustedClipRect.move(paintingInfo.subpixelAccumulation);
- context->clip(snapRectToDevicePixels(adjustedClipRect, deviceScaleFactor));
}
}
void RenderLayer::restoreClip(GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect)
{
- if (clipRect.rect() != paintDirtyRect || clipRect.hasRadius())
+ if (clipRect.rect() != paintDirtyRect || clipRect.affectedByRadius())
context->restore();
}
@@ -4397,10 +4401,10 @@
fragment.intersect(ancestorClipRect.rect());
// If the ancestor clip rect has border-radius, make sure to apply it to the fragments.
- if (ancestorClipRect.hasRadius()) {
- fragment.foregroundRect.setHasRadius(true);
- fragment.backgroundRect.setHasRadius(true);
- fragment.outlineRect.setHasRadius(true);
+ if (ancestorClipRect.affectedByRadius()) {
+ fragment.foregroundRect.setAffectedByRadius(true);
+ fragment.backgroundRect.setAffectedByRadius(true);
+ fragment.outlineRect.setAffectedByRadius(true);
}
// Now intersect with our pagination clip. This will typically mean we're just intersecting the dirty rect with the column
@@ -5304,7 +5308,7 @@
if (renderer().hasOverflowClip()) {
ClipRect newOverflowClip = downcast<RenderBox>(renderer()).overflowClipRectForChildLayers(offset, currentRenderNamedFlowFragment(), clipRectsContext.overlayScrollbarSizeRelevancy);
- newOverflowClip.setHasRadius(renderer().style().hasBorderRadius());
+ newOverflowClip.setAffectedByRadius(renderer().style().hasBorderRadius());
clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect()));
if (renderer().isPositioned())
clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect()));
@@ -5429,7 +5433,7 @@
if (renderer().hasOverflowClip() && (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip)) {
foregroundRect.intersect(downcast<RenderBox>(renderer()).overflowClipRect(toLayoutPoint(offsetFromRootLocal), namedFlowFragment, clipRectsContext.overlayScrollbarSizeRelevancy));
if (renderer().style().hasBorderRadius())
- foregroundRect.setHasRadius(true);
+ foregroundRect.setAffectedByRadius(true);
}
if (renderer().hasClip()) {
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (174985 => 174986)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2014-10-21 17:19:49 UTC (rev 174985)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2014-10-21 17:32:09 UTC (rev 174986)
@@ -84,30 +84,32 @@
class ClipRect {
public:
ClipRect()
- : m_hasRadius(false)
- { }
+ : m_affectedByRadius(false)
+ {
+ }
ClipRect(const LayoutRect& rect)
- : m_rect(rect)
- , m_hasRadius(false)
- { }
+ : m_rect(rect)
+ , m_affectedByRadius(false)
+ {
+ }
const LayoutRect& rect() const { return m_rect; }
void setRect(const LayoutRect& rect) { m_rect = rect; }
- bool hasRadius() const { return m_hasRadius; }
- void setHasRadius(bool hasRadius) { m_hasRadius = hasRadius; }
+ bool affectedByRadius() const { return m_affectedByRadius; }
+ void setAffectedByRadius(bool affectedByRadius) { m_affectedByRadius = affectedByRadius; }
- bool operator==(const ClipRect& other) const { return rect() == other.rect() && hasRadius() == other.hasRadius(); }
- bool operator!=(const ClipRect& other) const { return rect() != other.rect() || hasRadius() != other.hasRadius(); }
+ bool operator==(const ClipRect& other) const { return rect() == other.rect() && affectedByRadius() == other.affectedByRadius(); }
+ bool operator!=(const ClipRect& other) const { return rect() != other.rect() || affectedByRadius() != other.affectedByRadius(); }
bool operator!=(const LayoutRect& otherRect) const { return rect() != otherRect; }
void intersect(const LayoutRect& other) { m_rect.intersect(other); }
void intersect(const ClipRect& other)
{
m_rect.intersect(other.rect());
- if (other.hasRadius())
- m_hasRadius = true;
+ if (other.affectedByRadius())
+ m_affectedByRadius = true;
}
void move(LayoutUnit x, LayoutUnit y) { m_rect.move(x, y); }
void move(const LayoutSize& size) { m_rect.move(size); }
@@ -123,7 +125,7 @@
private:
LayoutRect m_rect;
- bool m_hasRadius;
+ bool m_affectedByRadius;
};
inline ClipRect intersection(const ClipRect& a, const ClipRect& b)