REGRESSION (r200283): Transform, overflow hidden and filter combination completely...
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Dec 2016 04:58:02 +0000 (04:58 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Dec 2016 04:58:02 +0000 (04:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=161509

Reviewed by David Hyatt.
Source/WebCore:

When the filter painting code needs to recompute a paintDirtyRect, it was using selfClipRect()
which is obviously wrong because it returns a rect in absolute coordinates. Use code factored
out of localClipRect() instead, which returns a rect relative to the painting root.

Test: css3/filters/filter-on-overflow-hidden.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintLayerContents):

LayoutTests:

* css3/filters/filter-on-overflow-hidden-expected.html: Added.
* css3/filters/filter-on-overflow-hidden.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209697 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/css3/filters/filter-on-overflow-hidden-expected.html [new file with mode: 0644]
LayoutTests/css3/filters/filter-on-overflow-hidden.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h

index 8599540..261672d 100644 (file)
@@ -1,3 +1,13 @@
+2016-12-11  Simon Fraser  <simon.fraser@apple.com>
+
+        REGRESSION (r200283): Transform, overflow hidden and filter combination completely hides the element
+        https://bugs.webkit.org/show_bug.cgi?id=161509
+
+        Reviewed by David Hyatt.
+
+        * css3/filters/filter-on-overflow-hidden-expected.html: Added.
+        * css3/filters/filter-on-overflow-hidden.html: Added.
+
 2016-12-11  Darin Adler  <darin@apple.com>
 
         Remove uses of Dictionary in WebRTC IDL files
diff --git a/LayoutTests/css3/filters/filter-on-overflow-hidden-expected.html b/LayoutTests/css3/filters/filter-on-overflow-hidden-expected.html
new file mode 100644 (file)
index 0000000..0f16c3a
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .parent {
+            position: absolute;
+            top: 50px;
+            left: 50px;
+            width: 100px;
+            height: 100px;
+            padding: 20px;
+            outline: 1px solid black;
+            transform: translateZ(0);
+        }
+        .box {
+            height: 100%;
+            width: 100%;
+            overflow: hidden;
+            background-color: green;
+        }
+        
+        .masker {
+            position: absolute;
+            top: 65px;
+            left: 65px;
+            width: 90px;
+            height: 90px;
+            border: 10px solid black;
+        }
+        
+    </style>
+</head>
+<body>
+    <div class="parent">
+        <div class="box">
+        </div>
+    </div>
+    
+    <div class="masker">
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/css3/filters/filter-on-overflow-hidden.html b/LayoutTests/css3/filters/filter-on-overflow-hidden.html
new file mode 100644 (file)
index 0000000..6e089c6
--- /dev/null
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .parent {
+            position: absolute;
+            top: 50px;
+            left: 50px;
+            width: 100px;
+            height: 100px;
+            padding: 20px;
+            outline: 1px solid black;
+            transform: translateZ(0);
+        }
+        .box {
+            height: 100%;
+            width: 100%;
+            overflow: hidden;
+            background-color: green;
+            filter: blur(2px);
+        }
+        
+        .masker {
+            position: absolute;
+            top: 65px;
+            left: 65px;
+            width: 90px;
+            height: 90px;
+            border: 10px solid black;
+        }
+        
+    </style>
+</head>
+<body>
+    <div class="parent">
+        <div class="box">
+        </div>
+    </div>
+    
+    <div class="masker">
+    </div>
+</body>
+</html>
index cbe44d0..c6a4898 100644 (file)
@@ -1,3 +1,19 @@
+2016-12-11  Simon Fraser  <simon.fraser@apple.com>
+
+        REGRESSION (r200283): Transform, overflow hidden and filter combination completely hides the element
+        https://bugs.webkit.org/show_bug.cgi?id=161509
+
+        Reviewed by David Hyatt.
+        
+        When the filter painting code needs to recompute a paintDirtyRect, it was using selfClipRect() 
+        which is obviously wrong because it returns a rect in absolute coordinates. Use code factored
+        out of localClipRect() instead, which returns a rect relative to the painting root.
+
+        Test: css3/filters/filter-on-overflow-hidden.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintLayerContents):
+
 2016-12-11  Saam Barati  <sbarati@apple.com>
 
         We should be able to throw exceptions from Wasm code and when Wasm frames are on the stack
index ef7075d..4d1d72c 100644 (file)
@@ -4390,7 +4390,7 @@ void RenderLayer::paintLayerContents(GraphicsContext& context, const LayerPainti
             if (!localPaintingInfo.clipToDirtyRect && renderer().hasOverflowClip()) {
                 // We can turn clipping back by requesting full repaint for the overflow area.
                 localPaintingInfo.clipToDirtyRect = true;
-                paintDirtyRect = selfClipRect();
+                paintDirtyRect = clipRectRelativeToAncestor(localPaintingInfo.rootLayer, offsetFromRoot, LayoutRect::infiniteRect());
             }
             collectFragments(layerFragments, localPaintingInfo.rootLayer, paintDirtyRect, ExcludeCompositedPaginatedLayers,
                 (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
@@ -5769,18 +5769,24 @@ LayoutRect RenderLayer::childrenClipRect() const
     return clippingRootLayer->renderer().localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox();
 }
 
+LayoutRect RenderLayer::clipRectRelativeToAncestor(RenderLayer* ancestor, LayoutSize offsetFromAncestor, const LayoutRect& constrainingRect) const
+{
+    LayoutRect layerBounds;
+    ClipRect backgroundRect;
+    ClipRect foregroundRect;
+    auto clipRectType = !m_enclosingPaginationLayer || m_enclosingPaginationLayer == ancestor ? PaintingClipRects : TemporaryClipRects;
+    ClipRectsContext clipRectsContext(ancestor, clipRectType);
+    calculateRects(clipRectsContext, constrainingRect, layerBounds, backgroundRect, foregroundRect, offsetFromAncestor);
+    return backgroundRect.rect();
+}
+
 LayoutRect RenderLayer::selfClipRect() const
 {
     // FIXME: border-radius not accounted for.
     // FIXME: Regions not accounted for.
     RenderLayer* clippingRootLayer = clippingRootForPainting();
-    LayoutRect layerBounds;
-    ClipRect backgroundRect;
-    ClipRect foregroundRect;
-    auto clipRectType = !m_enclosingPaginationLayer || m_enclosingPaginationLayer == clippingRootLayer ? PaintingClipRects : TemporaryClipRects;
-    ClipRectsContext clipRectsContext(clippingRootLayer, clipRectType);
-    calculateRects(clipRectsContext, renderer().view().documentRect(), layerBounds, backgroundRect, foregroundRect, offsetFromAncestor(clippingRootLayer));
-    return clippingRootLayer->renderer().localToAbsoluteQuad(FloatQuad(backgroundRect.rect())).enclosingBoundingBox();
+    LayoutRect clipRect = clipRectRelativeToAncestor(clippingRootLayer, offsetFromAncestor(clippingRootLayer), renderer().view().documentRect());
+    return clippingRootLayer->renderer().localToAbsoluteQuad(FloatQuad(clipRect)).enclosingBoundingBox();
 }
 
 LayoutRect RenderLayer::localClipRect(bool& clipExceedsBounds) const
@@ -5790,15 +5796,7 @@ LayoutRect RenderLayer::localClipRect(bool& clipExceedsBounds) const
     // FIXME: Regions not accounted for.
     RenderLayer* clippingRootLayer = clippingRootForPainting();
     LayoutSize offsetFromRoot = offsetFromAncestor(clippingRootLayer);
-
-    LayoutRect layerBounds;
-    ClipRect backgroundRect;
-    ClipRect foregroundRect;
-    auto clipRectType = !m_enclosingPaginationLayer || m_enclosingPaginationLayer == clippingRootLayer ? PaintingClipRects : TemporaryClipRects;
-    ClipRectsContext clipRectsContext(clippingRootLayer, clipRectType);
-    calculateRects(clipRectsContext, LayoutRect::infiniteRect(), layerBounds, backgroundRect, foregroundRect, offsetFromRoot);
-
-    LayoutRect clipRect = backgroundRect.rect();
+    LayoutRect clipRect = clipRectRelativeToAncestor(clippingRootLayer, offsetFromRoot, LayoutRect::infiniteRect());
     if (clipRect.isInfinite())
         return clipRect;
 
index 159aef6..0797455 100644 (file)
@@ -726,6 +726,8 @@ private:
     void computeRepaintRectsIncludingDescendants();
     void clearRepaintRects();
 
+    LayoutRect clipRectRelativeToAncestor(RenderLayer* ancestor, LayoutSize offsetFromAncestor, const LayoutRect& constrainingRect) const;
+
     void clipToRect(GraphicsContext&, const LayerPaintingInfo&, const ClipRect&, BorderRadiusClippingRule = IncludeSelfForBorderRadius);
     void restoreClip(GraphicsContext&, const LayerPaintingInfo&, const ClipRect&);