Title: [172146] trunk
Revision
172146
Author
stav...@adobe.com
Date
2014-08-06 08:06:08 -0700 (Wed, 06 Aug 2014)

Log Message

REGRESSION (r163382): Overflow hidden for inner elements breaks blurring
https://bugs.webkit.org/show_bug.cgi?id=135318

Reviewed by Zalan Bujtas.

Source/WebCore:

For elements with border radius, clipping must be applied using clipRoundedRect.
This regressed in r163382, when normal clipping started being applied also
for elements having border radius.

Test: fast/filter-image/clipped-filter.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::clipToRect):
(WebCore::RenderLayer::restoreClip):

LayoutTests:

Added test for filter applied on an element overflowing its parent, which has overflow:hidden.

* fast/filter-image/clipped-filter-expected.html: Added.
* fast/filter-image/clipped-filter.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (172145 => 172146)


--- trunk/LayoutTests/ChangeLog	2014-08-06 15:04:09 UTC (rev 172145)
+++ trunk/LayoutTests/ChangeLog	2014-08-06 15:06:08 UTC (rev 172146)
@@ -1,3 +1,15 @@
+2014-08-06  Radu Stavila  <stav...@adobe.com>
+
+        REGRESSION (r163382): Overflow hidden for inner elements breaks blurring
+        https://bugs.webkit.org/show_bug.cgi?id=135318
+
+        Reviewed by Zalan Bujtas.
+
+        Added test for filter applied on an element overflowing its parent, which has overflow:hidden.
+
+        * fast/filter-image/clipped-filter-expected.html: Added.
+        * fast/filter-image/clipped-filter.html: Added.
+
 2014-08-06  Mihnea Ovidenie  <mih...@adobe.com>
 
         [CSSRegions] Move selection tests under fast/regions/selection

Added: trunk/LayoutTests/fast/filter-image/clipped-filter-expected.html (0 => 172146)


--- trunk/LayoutTests/fast/filter-image/clipped-filter-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/filter-image/clipped-filter-expected.html	2014-08-06 15:06:08 UTC (rev 172146)
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .circle {
+            width: 300px;
+            height: 300px;
+            margin-left: 100px;
+            margin-top: 60px;
+            background-color: #f5ad61;
+            border-radius: 50% 50%;
+        }
+        .inner {
+            -webkit-filter: drop-shadow(16px 16px 0px black);
+            background-color: red;
+            height: 60px;
+            width: 200px;
+        }
+
+        #clip {
+            position: absolute;
+            top: 0px;
+            left: 0px;
+            width: 500px;
+            height: 500px;
+            background-color: white;
+            -webkit-clip-path: url(#clipPath);
+        }
+    </style>
+</head>
+
+<body>
+    <a href="" 135318 - This test passes if the red element has a black shadow and is clipped by the orange circle</a>
+
+    <div class="circle">
+        <div class="inner"></div>
+    </div>
+
+    <div id="clip"></div>
+</body>
+
+<svg>
+    <defs>
+        <clipPath id="clipPath">
+            <path d="M18,38 v200 h90 a150,150 0 0,1 300,0 h50 v-200 z"
+        </clipPath>
+    </defs>
+</svg>
+
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/fast/filter-image/clipped-filter.html (0 => 172146)


--- trunk/LayoutTests/fast/filter-image/clipped-filter.html	                        (rev 0)
+++ trunk/LayoutTests/fast/filter-image/clipped-filter.html	2014-08-06 15:06:08 UTC (rev 172146)
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .circle {
+            width: 300px;
+            height: 300px;
+            margin-left: 100px;
+            margin-top: 60px;
+            background-color: #f5ad61;
+            overflow: hidden;
+            border-radius: 50% 50%;
+        }
+
+        .inner {
+            -webkit-filter: drop-shadow(16px 16px 0px black);
+            background-color: red;
+            height: 60px;
+            width: 200px;
+        }
+
+        #clip {
+            position: absolute;
+            top: 0px;
+            left: 0px;
+            width: 500px;
+            height: 500px;
+            background-color: white;
+            -webkit-clip-path: url(#clipPath);
+        }
+    </style>
+</head>
+
+<body>
+    <a href="" 135318 - This test passes if the red element has a black shadow and is clipped by the orange circle</a>
+
+    <div class="circle">
+        <div class="inner"></div>
+    </div>
+
+    <div id="clip"></div>
+</body>
+
+<svg>
+    <defs>
+        <clipPath id="clipPath">
+            <path d="M18,38 v200 h90 a150,150 0 0,1 300,0 h50 v-200 z"
+        </clipPath>
+    </defs>
+</svg>
+
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (172145 => 172146)


--- trunk/Source/WebCore/ChangeLog	2014-08-06 15:04:09 UTC (rev 172145)
+++ trunk/Source/WebCore/ChangeLog	2014-08-06 15:06:08 UTC (rev 172146)
@@ -1,3 +1,20 @@
+2014-08-06  Radu Stavila  <stav...@adobe.com>
+
+        REGRESSION (r163382): Overflow hidden for inner elements breaks blurring
+        https://bugs.webkit.org/show_bug.cgi?id=135318
+
+        Reviewed by Zalan Bujtas.
+
+        For elements with border radius, clipping must be applied using clipRoundedRect.
+        This regressed in r163382, when normal clipping started being applied also
+        for elements having border radius.
+
+        Test: fast/filter-image/clipped-filter.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::clipToRect):
+        (WebCore::RenderLayer::restoreClip):
+
 2014-08-06  Zalan Bujtas  <za...@apple.com>
 
         Cleanup InlineTextBox::paintSelection and ::localSelectionRect.

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (172145 => 172146)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-08-06 15:04:09 UTC (rev 172145)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-08-06 15:06:08 UTC (rev 172146)
@@ -3586,36 +3586,34 @@
 void RenderLayer::clipToRect(const LayerPaintingInfo& paintingInfo, GraphicsContext* context, const ClipRect& clipRect, BorderRadiusClippingRule rule)
 {
     float deviceScaleFactor = renderer().document().deviceScaleFactor();
-    if (clipRect.rect() != paintingInfo.paintDirtyRect || clipRect.hasRadius()) {
+    if (clipRect.hasRadius()) {
         context->save();
+        
+        // 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.
+        for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) {
+            if (layer->renderer().hasOverflowClip() && layer->renderer().style().hasBorderRadius() && inContainingBlockChain(this, layer)) {
+                LayoutRect adjustedClipRect = LayoutRect(toLayoutPoint(layer->offsetFromAncestor(paintingInfo.rootLayer)), layer->size());
+                adjustedClipRect.move(paintingInfo.subpixelAccumulation);
+                context->clipRoundedRect(layer->renderer().style().getRoundedInnerBorderFor(adjustedClipRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor));
+            }
+            
+            if (layer == paintingInfo.rootLayer)
+                break;
+        }
+    } else if (clipRect.rect() != paintingInfo.paintDirtyRect) {
+        context->save();
         LayoutRect adjustedClipRect = clipRect.rect();
         adjustedClipRect.move(paintingInfo.subpixelAccumulation);
         context->clip(pixelSnappedForPainting(adjustedClipRect, deviceScaleFactor));
     }
-
-    if (!clipRect.hasRadius())
-        return;
-
-    // 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.
-    for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) {
-        if (layer->renderer().hasOverflowClip() && layer->renderer().style().hasBorderRadius() && inContainingBlockChain(this, layer)) {
-            LayoutRect adjustedClipRect = LayoutRect(toLayoutPoint(layer->offsetFromAncestor(paintingInfo.rootLayer)), layer->size());
-            adjustedClipRect.move(paintingInfo.subpixelAccumulation);
-            context->clipRoundedRect(layer->renderer().style().getRoundedInnerBorderFor(adjustedClipRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor));
-        }
-
-        if (layer == paintingInfo.rootLayer)
-            break;
-    }
 }
 
 void RenderLayer::restoreClip(GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect)
 {
-    if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius())
-        return;
-    context->restore();
+    if (clipRect.rect() != paintDirtyRect || clipRect.hasRadius())
+        context->restore();
 }
 
 static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, const RenderLayer* rootLayer, const RenderLayer* layer)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to