Title: [174986] trunk
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)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to