Filters need to affect visual overflow
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Dec 2011 18:01:09 +0000 (18:01 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Dec 2011 18:01:09 +0000 (18:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=71930

Source/WebCore:

Reviewed by Simon Fraser.

Make sure filters are included in visual overflow.
Add a new method to calculate the expansion of overflow
region given a list of FilterOperations. This is a slight
duplication of code from the rendering path, but is needed
because overflow is calculated before the FilterEffect
chain is built.

Also, filters were always rendered into their
input rectangle which was wrong for any effect
that produced a different sized result - drop-shadow
and blur. This required two changes. First, FilterEffect
needed a flag to decide whether or not to clip
output to primitive regions (as required by SVG but not
what we want here). Second, the rendering operation
draws into the rectangle the filter claims is its painting
rectangle.

Test: css3/filters/regions-expanding.html

* platform/graphics/filters/FEDropShadow.cpp:
(WebCore::FEDropShadow::determineAbsolutePaintRect): Only
clipToBounds if necessary.
* platform/graphics/filters/FEGaussianBlur.cpp:
(WebCore::FEGaussianBlur::calculateUnscaledKernelSize): CSS filters
ask for the kernel size before the Filter object is created, so
add a new method to return an unscaled kernel.
(WebCore::FEGaussianBlur::calculateKernelSize):
(WebCore::FEGaussianBlur::determineAbsolutePaintRect): Only
clipToBounds if necessary.
* platform/graphics/filters/FEGaussianBlur.h:
* platform/graphics/filters/FEMorphology.cpp:
(WebCore::FEMorphology::determineAbsolutePaintRect): Only
clipToBounds if necessary.
* platform/graphics/filters/FEOffset.cpp:
(WebCore::FEOffset::determineAbsolutePaintRect): Only
clipToBounds if necessary.
* platform/graphics/filters/FilterEffect.cpp:
(WebCore::FilterEffect::FilterEffect): Initialize clipToBounds
as false so SVG remains unchanged.
(WebCore::FilterEffect::determineAbsolutePaintRect): Only
clipToBounds if necessary.
* platform/graphics/filters/FilterEffect.h:
(WebCore::FilterEffect::clipsToBounds):
(WebCore::FilterEffect::setClipsToBounds):
* rendering/FilterEffectRenderer.cpp:
(WebCore::FilterEffectRenderer::build): Make sure we set our
filters here to NOT clip to bounds.
* rendering/FilterEffectRenderer.h:
(WebCore::FilterEffectRenderer::outputRect): Asks the filter
operation for the size of the result image.
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::computeOverflow):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::addVisualEffectOverflow): Change the name
from addBoxShadowAndBorderOverflow().
* rendering/RenderBox.h:
* rendering/RenderEmbeddedObject.cpp:
(WebCore::RenderEmbeddedObject::layout):
* rendering/RenderIFrame.cpp:
(WebCore::RenderIFrame::layout):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintLayer):
* rendering/RenderLayerBacking.cpp:
(WebCore::hasBoxDecorations): Change name from
hasBorderOutlineOrShadow().
(WebCore::hasBoxDecorationsOrBackground):
(WebCore::hasBoxDecorationsOrBackgroundImage):
* rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::layout):
* rendering/style/FilterOperations.cpp:
(WebCore::outsetSizeForBlur): Return an IntSize that is the amount
of offset.
(WebCore::FilterOperations::hasOutsets):
(WebCore::FilterOperations::getOutsets):
* rendering/style/FilterOperations.h:
* rendering/style/RenderStyle.h:
(WebCore::InheritedFlags::getFilterOutsets):
(WebCore::InheritedFlags::hasFilterOutsets):
* svg/graphics/filters/SVGFEImage.cpp:
(WebCore::FEImage::determineAbsolutePaintRect): Only
clipToBounds if necessary.

LayoutTests:

Previously, filters that expanded their input
region (drop-shadow and blur) were being squished
when rendered back into the document. This is now
fixed, so the expected.png images from tests including
such filters needed updating. I also turned off
dumpAsText() in order to enable pixel tests, and added
some margin between the elements in effects which have
overflow (so that blurs don't overlap, for example).

There is one new test which exercises the case
of expanding filters at various stages in a list
of operations.

Reviewed by Simon Fraser.

* css3/filters/crash-filter-change-expected.png:
* css3/filters/effect-blur-expected.png:
* css3/filters/effect-blur-expected.txt:
* css3/filters/effect-blur.html:
* css3/filters/effect-combined-expected.png:
* css3/filters/effect-combined-expected.txt:
* css3/filters/effect-combined.html:
* css3/filters/effect-drop-shadow-expected.png:
* css3/filters/effect-drop-shadow-expected.txt:
* css3/filters/effect-drop-shadow.html:
* css3/filters/effect-gamma-expected.txt:
* css3/filters/effect-gamma.html:
* css3/filters/effect-grayscale-expected.txt:
* css3/filters/effect-grayscale.html:
* css3/filters/effect-hue-rotate-expected.txt:
* css3/filters/effect-hue-rotate.html:
* css3/filters/effect-invert-expected.png:
* css3/filters/effect-invert-expected.txt:
* css3/filters/effect-invert.html:
* css3/filters/effect-opacity-expected.txt:
* css3/filters/effect-opacity.html:
* css3/filters/effect-saturate-expected.txt:
* css3/filters/effect-saturate.html:
* css3/filters/effect-sepia-expected.txt:
* css3/filters/effect-sepia.html:
* css3/filters/regions-expanding-expected.png: Added.
* css3/filters/regions-expanding-expected.txt: Added.
* css3/filters/regions-expanding.html: Added.

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

52 files changed:
LayoutTests/ChangeLog
LayoutTests/css3/filters/crash-filter-change-expected.png
LayoutTests/css3/filters/effect-blur-expected.png
LayoutTests/css3/filters/effect-blur-expected.txt
LayoutTests/css3/filters/effect-blur.html
LayoutTests/css3/filters/effect-combined-expected.png
LayoutTests/css3/filters/effect-combined-expected.txt
LayoutTests/css3/filters/effect-combined.html
LayoutTests/css3/filters/effect-drop-shadow-expected.png
LayoutTests/css3/filters/effect-drop-shadow-expected.txt
LayoutTests/css3/filters/effect-drop-shadow.html
LayoutTests/css3/filters/effect-gamma-expected.txt
LayoutTests/css3/filters/effect-gamma.html
LayoutTests/css3/filters/effect-grayscale-expected.txt
LayoutTests/css3/filters/effect-grayscale.html
LayoutTests/css3/filters/effect-hue-rotate-expected.txt
LayoutTests/css3/filters/effect-hue-rotate.html
LayoutTests/css3/filters/effect-invert-expected.png
LayoutTests/css3/filters/effect-invert-expected.txt
LayoutTests/css3/filters/effect-invert.html
LayoutTests/css3/filters/effect-opacity-expected.txt
LayoutTests/css3/filters/effect-opacity.html
LayoutTests/css3/filters/effect-saturate-expected.txt
LayoutTests/css3/filters/effect-saturate.html
LayoutTests/css3/filters/effect-sepia-expected.txt
LayoutTests/css3/filters/effect-sepia.html
LayoutTests/css3/filters/regions-expanding-expected.png [new file with mode: 0644]
LayoutTests/css3/filters/regions-expanding-expected.txt [new file with mode: 0644]
LayoutTests/css3/filters/regions-expanding.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/filters/FEDropShadow.cpp
Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
Source/WebCore/platform/graphics/filters/FEGaussianBlur.h
Source/WebCore/platform/graphics/filters/FEMorphology.cpp
Source/WebCore/platform/graphics/filters/FEOffset.cpp
Source/WebCore/platform/graphics/filters/FilterEffect.cpp
Source/WebCore/platform/graphics/filters/FilterEffect.h
Source/WebCore/platform/graphics/filters/FilterOperations.cpp
Source/WebCore/platform/graphics/filters/FilterOperations.h
Source/WebCore/rendering/FilterEffectRenderer.cpp
Source/WebCore/rendering/FilterEffectRenderer.h
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderEmbeddedObject.cpp
Source/WebCore/rendering/RenderIFrame.cpp
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderReplaced.cpp
Source/WebCore/rendering/style/RenderStyle.h
Source/WebCore/rendering/style/StyleFilterData.cpp
Source/WebCore/svg/graphics/filters/SVGFEImage.cpp

index 2b00b7e..e9d21f6 100644 (file)
@@ -1,3 +1,52 @@
+2011-12-16  Dean Jackson  <dino@apple.com>
+
+        Filters need to affect visual overflow
+        https://bugs.webkit.org/show_bug.cgi?id=71930
+
+        Previously, filters that expanded their input
+        region (drop-shadow and blur) were being squished
+        when rendered back into the document. This is now
+        fixed, so the expected.png images from tests including
+        such filters needed updating. I also turned off
+        dumpAsText() in order to enable pixel tests, and added
+        some margin between the elements in effects which have
+        overflow (so that blurs don't overlap, for example).
+
+        There is one new test which exercises the case
+        of expanding filters at various stages in a list
+        of operations.
+
+        Reviewed by Simon Fraser.
+
+        * css3/filters/crash-filter-change-expected.png:
+        * css3/filters/effect-blur-expected.png:
+        * css3/filters/effect-blur-expected.txt:
+        * css3/filters/effect-blur.html:
+        * css3/filters/effect-combined-expected.png:
+        * css3/filters/effect-combined-expected.txt:
+        * css3/filters/effect-combined.html:
+        * css3/filters/effect-drop-shadow-expected.png:
+        * css3/filters/effect-drop-shadow-expected.txt:
+        * css3/filters/effect-drop-shadow.html:
+        * css3/filters/effect-gamma-expected.txt:
+        * css3/filters/effect-gamma.html:
+        * css3/filters/effect-grayscale-expected.txt:
+        * css3/filters/effect-grayscale.html:
+        * css3/filters/effect-hue-rotate-expected.txt:
+        * css3/filters/effect-hue-rotate.html:
+        * css3/filters/effect-invert-expected.png:
+        * css3/filters/effect-invert-expected.txt:
+        * css3/filters/effect-invert.html:
+        * css3/filters/effect-opacity-expected.txt:
+        * css3/filters/effect-opacity.html:
+        * css3/filters/effect-saturate-expected.txt:
+        * css3/filters/effect-saturate.html:
+        * css3/filters/effect-sepia-expected.txt:
+        * css3/filters/effect-sepia.html:
+        * css3/filters/regions-expanding-expected.png: Added.
+        * css3/filters/regions-expanding-expected.txt: Added.
+        * css3/filters/regions-expanding.html: Added.
+
 2011-12-16  Philippe Normand  <pnormand@igalia.com>
 
         Unreviewed, skipping some svg tests still failing on GTK 64-bit after r103071.
index 906b0b6..a793d80 100644 (file)
Binary files a/LayoutTests/css3/filters/crash-filter-change-expected.png and b/LayoutTests/css3/filters/crash-filter-change-expected.png differ
index 49ef713..cefc61b 100644 (file)
Binary files a/LayoutTests/css3/filters/effect-blur-expected.png and b/LayoutTests/css3/filters/effect-blur-expected.png differ
index bac9c71..83c89a5 100644 (file)
@@ -1 +1,20 @@
-   
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (180,96) size 4x18
+        text run at (180,96) width 4: " "
+      RenderText {#text} at (364,96) size 4x18
+        text run at (364,96) width 4: " "
+      RenderText {#text} at (548,96) size 4x18
+        text run at (548,96) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (18,18) size 160x90
+  RenderImage {IMG} at (10,10) size 160x90
+layer at (202,18) size 160x90
+  RenderImage {IMG} at (194,10) size 160x90
+layer at (386,18) size 160x90
+  RenderImage {IMG} at (378,10) size 160x90
+layer at (570,18) size 160x90
+  RenderImage {IMG} at (562,10) size 160x90
index 1d53c30..ba63294 100644 (file)
@@ -1,7 +1,8 @@
-<script>
-if (window.layoutTestController)
-    window.layoutTestController.dumpAsText();
-</script>
+<style>
+img {
+    margin: 10px;
+}
+</style>
 <img style="-webkit-filter: blur(0)" src="resources/reference.png">
 <img style="-webkit-filter: blur(2px)" src="resources/reference.png">
 <img style="-webkit-filter: blur(3px 3px)" src="resources/reference.png">
index b000db6..c7bba8b 100644 (file)
Binary files a/LayoutTests/css3/filters/effect-combined-expected.png and b/LayoutTests/css3/filters/effect-combined-expected.png differ
index 163b4d3..288df80 100644 (file)
@@ -1 +1,24 @@
-    
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (180,96) size 4x18
+        text run at (180,96) width 4: " "
+      RenderText {#text} at (364,96) size 4x18
+        text run at (364,96) width 4: " "
+      RenderText {#text} at (548,96) size 4x18
+        text run at (548,96) width 4: " "
+      RenderText {#text} at (732,96) size 4x18
+        text run at (732,96) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (18,18) size 160x90
+  RenderImage {IMG} at (10,10) size 160x90
+layer at (202,18) size 160x90
+  RenderImage {IMG} at (194,10) size 160x90
+layer at (386,18) size 160x90
+  RenderImage {IMG} at (378,10) size 160x90
+layer at (570,18) size 160x90
+  RenderImage {IMG} at (562,10) size 160x90
+layer at (18,132) size 160x90
+  RenderImage {IMG} at (10,124) size 160x90
index 3d359f2..d0b4c48 100644 (file)
@@ -1,7 +1,8 @@
-<script>
-if (window.layoutTestController)
-    window.layoutTestController.dumpAsText();
-</script>
+<style>
+img {
+    margin: 10px;
+}
+</style>
 <img style="-webkit-filter: sepia() saturate(3) hue-rotate(180deg)" src="resources/reference.png">
 <img style="-webkit-filter: saturate(3) hue-rotate(90deg)" src="resources/reference.png">
 <img style="-webkit-filter: grayscale() blur(3px)" src="resources/reference.png">
index 18b6a6f..c7bc8d1 100644 (file)
Binary files a/LayoutTests/css3/filters/effect-drop-shadow-expected.png and b/LayoutTests/css3/filters/effect-drop-shadow-expected.png differ
index 163b4d3..5668e7c 100644 (file)
@@ -1 +1,24 @@
-    
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (190,106) size 4x18
+        text run at (190,106) width 4: " "
+      RenderText {#text} at (384,106) size 4x18
+        text run at (384,106) width 4: " "
+      RenderText {#text} at (578,106) size 4x18
+        text run at (578,106) width 4: " "
+      RenderText {#text} at (772,106) size 4x18
+        text run at (772,106) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (23,23) size 160x90
+  RenderImage {IMG} at (15,15) size 160x90
+layer at (217,23) size 160x90
+  RenderImage {IMG} at (209,15) size 160x90
+layer at (411,23) size 160x90
+  RenderImage {IMG} at (403,15) size 160x90
+layer at (605,23) size 160x90
+  RenderImage {IMG} at (597,15) size 160x90
+layer at (23,147) size 160x90
+  RenderImage {IMG} at (15,139) size 160x90
index 12e630d..9c62109 100644 (file)
@@ -1,7 +1,8 @@
-<script>
-if (window.layoutTestController)
-    window.layoutTestController.dumpAsText();
-</script>
+<style>
+img {
+    margin: 15px;
+}
+</style>
 <img style="-webkit-filter: drop-shadow(0 0 0 black)" src="resources/reference.png">
 <img style="-webkit-filter: drop-shadow(5px 5px 2px black)" src="resources/reference.png">
 <img style="-webkit-filter: drop-shadow(5px 5px 0px red)" src="resources/reference.png">
index b055673..f1b9930 100644 (file)
@@ -1 +1,28 @@
-     
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (160,76) size 4x18
+        text run at (160,76) width 4: " "
+      RenderText {#text} at (324,76) size 4x18
+        text run at (324,76) width 4: " "
+      RenderText {#text} at (488,76) size 4x18
+        text run at (488,76) width 4: " "
+      RenderText {#text} at (652,76) size 4x18
+        text run at (652,76) width 4: " "
+      RenderText {#text} at (160,170) size 4x18
+        text run at (160,170) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,8) size 160x90
+  RenderImage {IMG} at (0,0) size 160x90
+layer at (172,8) size 160x90
+  RenderImage {IMG} at (164,0) size 160x90
+layer at (336,8) size 160x90
+  RenderImage {IMG} at (328,0) size 160x90
+layer at (500,8) size 160x90
+  RenderImage {IMG} at (492,0) size 160x90
+layer at (8,102) size 160x90
+  RenderImage {IMG} at (0,94) size 160x90
+layer at (172,102) size 160x90
+  RenderImage {IMG} at (164,94) size 160x90
index 37a9e99..ef2eaaa 100644 (file)
@@ -1,7 +1,3 @@
-<script>
-if (window.layoutTestController)
-    window.layoutTestController.dumpAsText();
-</script>
 <img style="-webkit-filter: gamma(1 1 0)" src="resources/reference.png">
 <img style="-webkit-filter: gamma(2 1 0)" src="resources/reference.png">
 <img style="-webkit-filter: gamma(1 1 0.2)" src="resources/reference.png">
index b055673..f1b9930 100644 (file)
@@ -1 +1,28 @@
-     
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (160,76) size 4x18
+        text run at (160,76) width 4: " "
+      RenderText {#text} at (324,76) size 4x18
+        text run at (324,76) width 4: " "
+      RenderText {#text} at (488,76) size 4x18
+        text run at (488,76) width 4: " "
+      RenderText {#text} at (652,76) size 4x18
+        text run at (652,76) width 4: " "
+      RenderText {#text} at (160,170) size 4x18
+        text run at (160,170) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,8) size 160x90
+  RenderImage {IMG} at (0,0) size 160x90
+layer at (172,8) size 160x90
+  RenderImage {IMG} at (164,0) size 160x90
+layer at (336,8) size 160x90
+  RenderImage {IMG} at (328,0) size 160x90
+layer at (500,8) size 160x90
+  RenderImage {IMG} at (492,0) size 160x90
+layer at (8,102) size 160x90
+  RenderImage {IMG} at (0,94) size 160x90
+layer at (172,102) size 160x90
+  RenderImage {IMG} at (164,94) size 160x90
index 6b9f25b..ad23937 100644 (file)
@@ -1,7 +1,3 @@
-<script>
-if (window.layoutTestController)
-    window.layoutTestController.dumpAsText();
-</script>
 <img style="-webkit-filter: grayscale(0)" src="resources/reference.png">
 <img style="-webkit-filter: grayscale(0.2)" src="resources/reference.png">
 <img style="-webkit-filter: grayscale(0.4)" src="resources/reference.png">
index b055673..f1b9930 100644 (file)
@@ -1 +1,28 @@
-     
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (160,76) size 4x18
+        text run at (160,76) width 4: " "
+      RenderText {#text} at (324,76) size 4x18
+        text run at (324,76) width 4: " "
+      RenderText {#text} at (488,76) size 4x18
+        text run at (488,76) width 4: " "
+      RenderText {#text} at (652,76) size 4x18
+        text run at (652,76) width 4: " "
+      RenderText {#text} at (160,170) size 4x18
+        text run at (160,170) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,8) size 160x90
+  RenderImage {IMG} at (0,0) size 160x90
+layer at (172,8) size 160x90
+  RenderImage {IMG} at (164,0) size 160x90
+layer at (336,8) size 160x90
+  RenderImage {IMG} at (328,0) size 160x90
+layer at (500,8) size 160x90
+  RenderImage {IMG} at (492,0) size 160x90
+layer at (8,102) size 160x90
+  RenderImage {IMG} at (0,94) size 160x90
+layer at (172,102) size 160x90
+  RenderImage {IMG} at (164,94) size 160x90
index db162fb..db0aba1 100644 (file)
@@ -1,7 +1,3 @@
-<script>
-if (window.layoutTestController)
-    window.layoutTestController.dumpAsText();
-</script>
 <img style="-webkit-filter: hue-rotate(0deg)" src="resources/reference.png">
 <img style="-webkit-filter: hue-rotate(45deg)" src="resources/reference.png">
 <img style="-webkit-filter: hue-rotate(90deg)" src="resources/reference.png">
index cf8507d..99e1b9b 100644 (file)
Binary files a/LayoutTests/css3/filters/effect-invert-expected.png and b/LayoutTests/css3/filters/effect-invert-expected.png differ
index b055673..f1b9930 100644 (file)
@@ -1 +1,28 @@
-     
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (160,76) size 4x18
+        text run at (160,76) width 4: " "
+      RenderText {#text} at (324,76) size 4x18
+        text run at (324,76) width 4: " "
+      RenderText {#text} at (488,76) size 4x18
+        text run at (488,76) width 4: " "
+      RenderText {#text} at (652,76) size 4x18
+        text run at (652,76) width 4: " "
+      RenderText {#text} at (160,170) size 4x18
+        text run at (160,170) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,8) size 160x90
+  RenderImage {IMG} at (0,0) size 160x90
+layer at (172,8) size 160x90
+  RenderImage {IMG} at (164,0) size 160x90
+layer at (336,8) size 160x90
+  RenderImage {IMG} at (328,0) size 160x90
+layer at (500,8) size 160x90
+  RenderImage {IMG} at (492,0) size 160x90
+layer at (8,102) size 160x90
+  RenderImage {IMG} at (0,94) size 160x90
+layer at (172,102) size 160x90
+  RenderImage {IMG} at (164,94) size 160x90
index 708ba9c..de0afb1 100644 (file)
@@ -1,7 +1,3 @@
-<script>
-if (window.layoutTestController)
-    window.layoutTestController.dumpAsText();
-</script>
 <img style="-webkit-filter: invert(0)" src="resources/reference.png">
 <img style="-webkit-filter: invert(0.2)" src="resources/reference.png">
 <img style="-webkit-filter: invert(0.4)" src="resources/reference.png">
index b055673..f1b9930 100644 (file)
@@ -1 +1,28 @@
-     
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (160,76) size 4x18
+        text run at (160,76) width 4: " "
+      RenderText {#text} at (324,76) size 4x18
+        text run at (324,76) width 4: " "
+      RenderText {#text} at (488,76) size 4x18
+        text run at (488,76) width 4: " "
+      RenderText {#text} at (652,76) size 4x18
+        text run at (652,76) width 4: " "
+      RenderText {#text} at (160,170) size 4x18
+        text run at (160,170) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,8) size 160x90
+  RenderImage {IMG} at (0,0) size 160x90
+layer at (172,8) size 160x90
+  RenderImage {IMG} at (164,0) size 160x90
+layer at (336,8) size 160x90
+  RenderImage {IMG} at (328,0) size 160x90
+layer at (500,8) size 160x90
+  RenderImage {IMG} at (492,0) size 160x90
+layer at (8,102) size 160x90
+  RenderImage {IMG} at (0,94) size 160x90
+layer at (172,102) size 160x90
+  RenderImage {IMG} at (164,94) size 160x90
index e9d6bb2..2ef0279 100644 (file)
@@ -1,7 +1,3 @@
-<script>
-if (window.layoutTestController)
-    window.layoutTestController.dumpAsText();
-</script>
 <img style="-webkit-filter: opacity(0)" src="resources/reference.png">
 <img style="-webkit-filter: opacity(0.2)" src="resources/reference.png">
 <img style="-webkit-filter: opacity(0.4)" src="resources/reference.png">
index b055673..f1b9930 100644 (file)
@@ -1 +1,28 @@
-     
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (160,76) size 4x18
+        text run at (160,76) width 4: " "
+      RenderText {#text} at (324,76) size 4x18
+        text run at (324,76) width 4: " "
+      RenderText {#text} at (488,76) size 4x18
+        text run at (488,76) width 4: " "
+      RenderText {#text} at (652,76) size 4x18
+        text run at (652,76) width 4: " "
+      RenderText {#text} at (160,170) size 4x18
+        text run at (160,170) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,8) size 160x90
+  RenderImage {IMG} at (0,0) size 160x90
+layer at (172,8) size 160x90
+  RenderImage {IMG} at (164,0) size 160x90
+layer at (336,8) size 160x90
+  RenderImage {IMG} at (328,0) size 160x90
+layer at (500,8) size 160x90
+  RenderImage {IMG} at (492,0) size 160x90
+layer at (8,102) size 160x90
+  RenderImage {IMG} at (0,94) size 160x90
+layer at (172,102) size 160x90
+  RenderImage {IMG} at (164,94) size 160x90
index 2425ebd..ce87a06 100644 (file)
@@ -1,7 +1,3 @@
-<script>
-if (window.layoutTestController)
-    window.layoutTestController.dumpAsText();
-</script>
 <img style="-webkit-filter: saturate(0)" src="resources/reference.png">
 <img style="-webkit-filter: saturate(0.5)" src="resources/reference.png">
 <img style="-webkit-filter: saturate(1.0)" src="resources/reference.png">
index b055673..f1b9930 100644 (file)
@@ -1 +1,28 @@
-     
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (160,76) size 4x18
+        text run at (160,76) width 4: " "
+      RenderText {#text} at (324,76) size 4x18
+        text run at (324,76) width 4: " "
+      RenderText {#text} at (488,76) size 4x18
+        text run at (488,76) width 4: " "
+      RenderText {#text} at (652,76) size 4x18
+        text run at (652,76) width 4: " "
+      RenderText {#text} at (160,170) size 4x18
+        text run at (160,170) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,8) size 160x90
+  RenderImage {IMG} at (0,0) size 160x90
+layer at (172,8) size 160x90
+  RenderImage {IMG} at (164,0) size 160x90
+layer at (336,8) size 160x90
+  RenderImage {IMG} at (328,0) size 160x90
+layer at (500,8) size 160x90
+  RenderImage {IMG} at (492,0) size 160x90
+layer at (8,102) size 160x90
+  RenderImage {IMG} at (0,94) size 160x90
+layer at (172,102) size 160x90
+  RenderImage {IMG} at (164,94) size 160x90
index a4bd8f8..c983875 100644 (file)
@@ -1,7 +1,3 @@
-<script>
-if (window.layoutTestController)
-    window.layoutTestController.dumpAsText();
-</script>
 <img style="-webkit-filter: sepia(0)" src="resources/reference.png">
 <img style="-webkit-filter: sepia(0.2)" src="resources/reference.png">
 <img style="-webkit-filter: sepia(0.4)" src="resources/reference.png">
diff --git a/LayoutTests/css3/filters/regions-expanding-expected.png b/LayoutTests/css3/filters/regions-expanding-expected.png
new file mode 100644 (file)
index 0000000..413069c
Binary files /dev/null and b/LayoutTests/css3/filters/regions-expanding-expected.png differ
diff --git a/LayoutTests/css3/filters/regions-expanding-expected.txt b/LayoutTests/css3/filters/regions-expanding-expected.txt
new file mode 100644 (file)
index 0000000..2c893d3
--- /dev/null
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (160,76) size 4x18
+        text run at (160,76) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+      RenderText {#text} at (324,76) size 4x18
+        text run at (324,76) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,8) size 160x90
+  RenderImage {IMG} at (0,0) size 160x90
+layer at (172,8) size 160x90
+  RenderImage {IMG} at (164,0) size 160x90
+layer at (336,8) size 160x90
+  RenderImage {IMG} at (328,0) size 160x90
diff --git a/LayoutTests/css3/filters/regions-expanding.html b/LayoutTests/css3/filters/regions-expanding.html
new file mode 100644 (file)
index 0000000..85b1161
--- /dev/null
@@ -0,0 +1,6 @@
+<!-- blur (expands) then sepia (shouldn't clamp) -->
+<img style="-webkit-filter: blur(2px) sepia()" src="resources/reference.png">
+<!-- blur (expands) then another blur (shouldn't clamp) -->
+<img style="-webkit-filter: blur(3px) blur(3px)" src="resources/reference.png">
+<!-- blur (expands) then grayscale then another blur (shouldn't clamp) -->
+<img style="-webkit-filter: blur(3px) grayscale() blur(3px)" src="resources/reference.png">
index 76a03d5..70f4286 100644 (file)
@@ -1,3 +1,92 @@
+2011-12-16  Dean Jackson  <dino@apple.com>
+
+        Filters need to affect visual overflow
+        https://bugs.webkit.org/show_bug.cgi?id=71930
+
+        Reviewed by Simon Fraser.
+
+        Make sure filters are included in visual overflow.
+        Add a new method to calculate the expansion of overflow
+        region given a list of FilterOperations. This is a slight
+        duplication of code from the rendering path, but is needed
+        because overflow is calculated before the FilterEffect
+        chain is built.
+
+        Also, filters were always rendered into their
+        input rectangle which was wrong for any effect
+        that produced a different sized result - drop-shadow
+        and blur. This required two changes. First, FilterEffect
+        needed a flag to decide whether or not to clip
+        output to primitive regions (as required by SVG but not
+        what we want here). Second, the rendering operation
+        draws into the rectangle the filter claims is its painting
+        rectangle.
+
+        Test: css3/filters/regions-expanding.html
+
+        * platform/graphics/filters/FEDropShadow.cpp:
+        (WebCore::FEDropShadow::determineAbsolutePaintRect): Only
+        clipToBounds if necessary.
+        * platform/graphics/filters/FEGaussianBlur.cpp:
+        (WebCore::FEGaussianBlur::calculateUnscaledKernelSize): CSS filters
+        ask for the kernel size before the Filter object is created, so
+        add a new method to return an unscaled kernel.
+        (WebCore::FEGaussianBlur::calculateKernelSize):
+        (WebCore::FEGaussianBlur::determineAbsolutePaintRect): Only
+        clipToBounds if necessary.
+        * platform/graphics/filters/FEGaussianBlur.h:
+        * platform/graphics/filters/FEMorphology.cpp:
+        (WebCore::FEMorphology::determineAbsolutePaintRect): Only
+        clipToBounds if necessary.
+        * platform/graphics/filters/FEOffset.cpp:
+        (WebCore::FEOffset::determineAbsolutePaintRect): Only
+        clipToBounds if necessary.
+        * platform/graphics/filters/FilterEffect.cpp:
+        (WebCore::FilterEffect::FilterEffect): Initialize clipToBounds
+        as false so SVG remains unchanged.
+        (WebCore::FilterEffect::determineAbsolutePaintRect): Only
+        clipToBounds if necessary.
+        * platform/graphics/filters/FilterEffect.h:
+        (WebCore::FilterEffect::clipsToBounds):
+        (WebCore::FilterEffect::setClipsToBounds):
+        * rendering/FilterEffectRenderer.cpp:
+        (WebCore::FilterEffectRenderer::build): Make sure we set our
+        filters here to NOT clip to bounds.
+        * rendering/FilterEffectRenderer.h:
+        (WebCore::FilterEffectRenderer::outputRect): Asks the filter
+        operation for the size of the result image.
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::computeOverflow):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::addVisualEffectOverflow): Change the name
+        from addBoxShadowAndBorderOverflow().
+        * rendering/RenderBox.h:
+        * rendering/RenderEmbeddedObject.cpp:
+        (WebCore::RenderEmbeddedObject::layout):
+        * rendering/RenderIFrame.cpp:
+        (WebCore::RenderIFrame::layout):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintLayer):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::hasBoxDecorations): Change name from
+        hasBorderOutlineOrShadow().
+        (WebCore::hasBoxDecorationsOrBackground):
+        (WebCore::hasBoxDecorationsOrBackgroundImage):
+        * rendering/RenderReplaced.cpp:
+        (WebCore::RenderReplaced::layout):
+        * rendering/style/FilterOperations.cpp:
+        (WebCore::outsetSizeForBlur): Return an IntSize that is the amount
+        of offset.
+        (WebCore::FilterOperations::hasOutsets):
+        (WebCore::FilterOperations::getOutsets):
+        * rendering/style/FilterOperations.h:
+        * rendering/style/RenderStyle.h:
+        (WebCore::InheritedFlags::getFilterOutsets):
+        (WebCore::InheritedFlags::hasFilterOutsets):
+        * svg/graphics/filters/SVGFEImage.cpp:
+        (WebCore::FEImage::determineAbsolutePaintRect): Only
+        clipToBounds if necessary.
+
 2011-12-16  Alexis Menard  <alexis.menard@openbossa.org>, Jakub Wieczorek  <jwieczorek@webkit.org>
 
         Add support for <ol reversed>.
index a60cc34..5d80778 100644 (file)
@@ -61,7 +61,10 @@ void FEDropShadow::determineAbsolutePaintRect()
     FloatRect absoluteOffsetPaintRect(absolutePaintRect);
     absoluteOffsetPaintRect.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy));
     absolutePaintRect.unite(absoluteOffsetPaintRect);
-    absolutePaintRect.intersect(maxEffectRect());
+    if (clipsToBounds())
+        absolutePaintRect.intersect(maxEffectRect());
+    else
+        absolutePaintRect.unite(maxEffectRect());
     
     unsigned kernelSizeX = 0;
     unsigned kernelSizeY = 0;
index 85ef8f6..f9a86eb 100644 (file)
@@ -228,11 +228,8 @@ inline void FEGaussianBlur::platformApply(ByteArray* srcPixelArray, ByteArray* t
 #endif
 }
 
-void FEGaussianBlur::calculateKernelSize(Filter* filter, unsigned& kernelSizeX, unsigned& kernelSizeY, float stdX, float stdY)
+void FEGaussianBlur::calculateUnscaledKernelSize(unsigned& kernelSizeX, unsigned& kernelSizeY, float stdX, float stdY)
 {
-    stdX = filter->applyHorizontalScale(stdX);
-    stdY = filter->applyVerticalScale(stdY);
-    
     kernelSizeX = 0;
     if (stdX)
         kernelSizeX = max<unsigned>(2, static_cast<unsigned>(floorf(stdX * gaussianKernelFactor() + 0.5f)));
@@ -248,10 +245,21 @@ void FEGaussianBlur::calculateKernelSize(Filter* filter, unsigned& kernelSizeX,
         kernelSizeY = gMaxKernelSize;
 }
 
+void FEGaussianBlur::calculateKernelSize(Filter* filter, unsigned& kernelSizeX, unsigned& kernelSizeY, float stdX, float stdY)
+{
+    stdX = filter->applyHorizontalScale(stdX);
+    stdY = filter->applyVerticalScale(stdY);
+
+    calculateUnscaledKernelSize(kernelSizeX, kernelSizeY, stdX, stdY);
+}
+
 void FEGaussianBlur::determineAbsolutePaintRect()
 {
     FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect();
-    absolutePaintRect.intersect(maxEffectRect());
+    if (clipsToBounds())
+        absolutePaintRect.intersect(maxEffectRect());
+    else
+        absolutePaintRect.unite(maxEffectRect());
 
     unsigned kernelSizeX = 0;
     unsigned kernelSizeY = 0;
index 7154b4f..7f6c3bb 100644 (file)
@@ -45,6 +45,7 @@ public:
     
     virtual void determineAbsolutePaintRect();
     static void calculateKernelSize(Filter*, unsigned& kernelSizeX, unsigned& kernelSizeY, float stdX, float stdY);
+    static void calculateUnscaledKernelSize(unsigned& kernelSizeX, unsigned& kernelSizeY, float stdX, float stdY);
 
     virtual TextStream& externalRepresentation(TextStream&, int indention) const;
 
index bd75e2b..5ba4dfc 100644 (file)
@@ -89,7 +89,10 @@ void FEMorphology::determineAbsolutePaintRect()
     Filter* filter = this->filter();
     paintRect.inflateX(filter->applyHorizontalScale(m_radiusX));
     paintRect.inflateY(filter->applyVerticalScale(m_radiusY));
-    paintRect.intersect(maxEffectRect());
+    if (clipsToBounds())
+        paintRect.intersect(maxEffectRect());
+    else
+        paintRect.unite(maxEffectRect());
     setAbsolutePaintRect(enclosingIntRect(paintRect));
 }
 
index d8196e0..ef2c466 100644 (file)
@@ -70,7 +70,10 @@ void FEOffset::determineAbsolutePaintRect()
     FloatRect paintRect = inputEffect(0)->absolutePaintRect();
     Filter* filter = this->filter();
     paintRect.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy));
-    paintRect.intersect(maxEffectRect());
+    if (clipsToBounds())
+        paintRect.intersect(maxEffectRect());
+    else
+        paintRect.unite(maxEffectRect());
     setAbsolutePaintRect(enclosingIntRect(paintRect));
 }
 
index dc5302c..6516faa 100644 (file)
@@ -38,6 +38,7 @@ FilterEffect::FilterEffect(Filter* filter)
     , m_hasY(false)
     , m_hasWidth(false)
     , m_hasHeight(false)
+    , m_clipsToBounds(true)
 {
     ASSERT(m_filter);
 }
@@ -61,8 +62,12 @@ void FilterEffect::determineAbsolutePaintRect()
     for (unsigned i = 0; i < size; ++i)
         m_absolutePaintRect.unite(m_inputEffects.at(i)->absolutePaintRect());
     
-    // SVG specification wants us to clip to primitive subregion.
-    m_absolutePaintRect.intersect(enclosingIntRect(m_maxEffectRect));
+    // Filters in SVG clip to primitive subregion, while CSS doesn't.
+    if (m_clipsToBounds)
+        m_absolutePaintRect.intersect(enclosingIntRect(m_maxEffectRect));
+    else
+        m_absolutePaintRect.unite(enclosingIntRect(m_maxEffectRect));
+    
 }
 
 IntRect FilterEffect::requestedRegionOfInputImageData(const IntRect& effectRect) const
index 13956c2..073010d 100644 (file)
@@ -118,6 +118,9 @@ public:
 
     Filter* filter() { return m_filter; }
 
+    bool clipsToBounds() const { return m_clipsToBounds; }
+    void setClipsToBounds(bool value) { m_clipsToBounds = value; }
+
 protected:
     FilterEffect(Filter*);
 
@@ -139,7 +142,7 @@ private:
     // The absolute paint rect should never be bigger than m_maxEffectRect.
     FloatRect m_maxEffectRect;
     Filter* m_filter;
-
+    
 private:
     inline void copyImageBytes(ByteArray* source, ByteArray* destination, const IntRect&);
 
@@ -157,6 +160,9 @@ private:
     bool m_hasY;
     bool m_hasWidth;
     bool m_hasHeight;
+
+    // Should the effect clip to its primitive region, or expand to use the combined region of its inputs.
+    bool m_clipsToBounds;
 };
 
 } // namespace WebCore
index fe19038..a9cb9d2 100644 (file)
 #include "config.h"
 #include "FilterOperations.h"
 
+#include "FEGaussianBlur.h"
+#include "IntSize.h"
+
 #if ENABLE(CSS_FILTERS)
 
 namespace WebCore {
 
+static inline IntSize outsetSizeForBlur(float stdX, float stdY)
+{
+    unsigned kernelSizeX = 0;
+    unsigned kernelSizeY = 0;
+    FEGaussianBlur::calculateUnscaledKernelSize(kernelSizeX, kernelSizeY, stdX, stdY);
+
+    IntSize outset;
+    // We take the half kernel size and multiply it with three, because we run box blur three times.
+    outset.setWidth(3 * kernelSizeX * 0.5f);
+    outset.setHeight(3 * kernelSizeY * 0.5f);
+
+    return outset;
+}
+
 FilterOperations::FilterOperations()
 {
 }
@@ -63,6 +80,57 @@ bool FilterOperations::operationsMatch(const FilterOperations& other) const
     return true;
 }
 
+bool FilterOperations::hasOutsets() const
+{
+    for (size_t i = 0; i < m_operations.size(); ++i) {
+        FilterOperation::OperationType operationType = m_operations.at(i).get()->getOperationType();
+        if (operationType == FilterOperation::BLUR || operationType == FilterOperation::DROP_SHADOW)
+            return true;
+    }
+    return false;
+}
+
+void FilterOperations::getOutsets(LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left, const LayoutSize& borderBoxSize) const
+{
+    top = 0;
+    right = 0;
+    bottom = 0;
+    left = 0;
+    for (size_t i = 0; i < m_operations.size(); ++i) {
+        FilterOperation* filterOperation = m_operations.at(i).get();
+        switch (filterOperation->getOperationType()) {
+        case FilterOperation::BLUR: {
+            BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation);
+            float stdDeviationX = blurOperation->stdDeviationX().calcFloatValue(borderBoxSize.width());
+            float stdDeviationY = blurOperation->stdDeviationY().calcFloatValue(borderBoxSize.height());
+            IntSize outset = outsetSizeForBlur(stdDeviationX, stdDeviationY);
+            top += outset.height();
+            right += outset.width();
+            bottom += outset.height();
+            left += outset.width();
+            break;
+        }
+        case FilterOperation::DROP_SHADOW: {
+            DropShadowFilterOperation* dropShadowOperation = static_cast<DropShadowFilterOperation*>(filterOperation);
+            IntSize outset = outsetSizeForBlur(dropShadowOperation->stdDeviation(), dropShadowOperation->stdDeviation());
+            top += outset.height() - dropShadowOperation->y();
+            right += outset.width() + dropShadowOperation->x();
+            bottom += outset.height() + dropShadowOperation->y();
+            left += outset.width() - dropShadowOperation->x();
+            break;
+        }
+#if ENABLE(CSS_SHADERS)
+        case FilterOperation::CUSTOM: {
+            // Need to include the filter margins here.
+            break;
+        }
+#endif
+        default:
+            break;
+        }
+    }
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(CSS_FILTERS)
index bf193f5..22b508c 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(CSS_FILTERS)
 
 #include "FilterOperation.h"
+#include "LayoutTypes.h"
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
@@ -58,6 +59,9 @@ public:
 
     bool operationsMatch(const FilterOperations&) const;
 
+    bool hasOutsets() const;
+    void getOutsets(LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left, const LayoutSize& borderBoxSize) const;
+
 private:
     Vector<RefPtr<FilterOperation> > m_operations;
 };
index 467c499..e66ef5e 100644 (file)
@@ -223,6 +223,9 @@ void FilterEffectRenderer::build(const FilterOperations& operations, const Layou
         }
 
         if (effect) {
+            // Unlike SVG, filters applied here should not clip to their primitive subregions.
+            effect->setClipsToBounds(false);
+            
             if (previousEffect)
                 effect->inputEffects().append(previousEffect);
             m_effects.append(effect);
index 0bafac8..1d684d3 100644 (file)
@@ -71,6 +71,8 @@ public:
     void prepare();
     void apply();
     
+    IntRect outputRect() const { return lastEffect()->hasResult() ? lastEffect()->requestedRegionOfInputImageData(IntRect(m_filterRegion)) : IntRect(); }
+    
 private:
 
     void setMaxEffectRects(const FloatRect& effectRect)
index 7cc3de2..aeabe1e 100755 (executable)
@@ -1451,7 +1451,7 @@ void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeF
     }
         
     // Add visual overflow from box-shadow and border-image-outset.
-    addBoxShadowAndBorderOverflow();
+    addVisualEffectOverflow();
 }
 
 void RenderBlock::addOverflowFromBlockChildren()
index 9517ae4..25635a6 100644 (file)
@@ -3516,9 +3516,9 @@ bool RenderBox::avoidsFloats() const
     return isReplaced() || hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot() || isDeprecatedFlexItem();
 }
 
-void RenderBox::addBoxShadowAndBorderOverflow()
+void RenderBox::addVisualEffectOverflow()
 {
-    if (!style()->boxShadow() && !style()->hasBorderImageOutsets())
+    if (!style()->boxShadow() && !style()->hasBorderImageOutsets() && !style()->hasFilterOutsets())
         return;
 
     bool isFlipped = style()->isFlippedBlocksWritingMode();
@@ -3561,6 +3561,21 @@ void RenderBox::addBoxShadowAndBorderOverflow()
         overflowMaxY = max(overflowMaxY, borderBox.maxY() + ((!isFlipped || !isHorizontal) ? borderOutsetBottom : borderOutsetTop));
     }
 
+#if ENABLE(CSS_FILTERS)
+    // Compute any filter outset overflow.
+    if (style()->hasFilterOutsets()) {
+        LayoutUnit filterOutsetLeft;
+        LayoutUnit filterOutsetRight;
+        LayoutUnit filterOutsetTop;
+        LayoutUnit filterOutsetBottom;
+        style()->getFilterOutsets(filterOutsetTop, filterOutsetRight, filterOutsetBottom, filterOutsetLeft, borderBox.size());
+        
+        overflowMinX = min(overflowMinX, borderBox.x() - filterOutsetLeft);
+        overflowMaxX = max(overflowMaxX, borderBox.maxX() + filterOutsetRight);
+        overflowMinY = min(overflowMinY, borderBox.y() - filterOutsetTop);
+        overflowMaxY = max(overflowMaxY, borderBox.maxY() + filterOutsetBottom);
+    }
+#endif
     // Add in the final overflow with shadows and outsets combined.
     addVisualOverflow(LayoutRect(overflowMinX, overflowMinY, overflowMaxX - overflowMinX, overflowMaxY - overflowMinY));
 }
index e4eef65..d72754a 100644 (file)
@@ -166,7 +166,7 @@ public:
     void addLayoutOverflow(const LayoutRect&);
     void addVisualOverflow(const LayoutRect&);
     
-    void addBoxShadowAndBorderOverflow();
+    void addVisualEffectOverflow();
     void addOverflowFromChild(RenderBox* child) { addOverflowFromChild(child, child->locationOffset()); }
     void addOverflowFromChild(RenderBox* child, const LayoutSize& delta);
     void clearLayoutOverflow();
index 5425bc6..d1d77a0 100644 (file)
@@ -222,7 +222,7 @@ void RenderEmbeddedObject::layout()
     RenderPart::layout();
 
     m_overflow.clear();
-    addBoxShadowAndBorderOverflow();
+    addVisualEffectOverflow();
 
     updateLayerTransform();
 
index ce0f43b..7e87383 100644 (file)
@@ -124,7 +124,7 @@ void RenderIFrame::layout()
     RenderPart::layout();
 
     m_overflow.clear();
-    addBoxShadowAndBorderOverflow();
+    addVisualEffectOverflow();
     updateLayerTransform();
 
     setNeedsLayout(false);
index 4266d07..517b30f 100644 (file)
@@ -2764,8 +2764,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
         transform.translateRight(layerOrigin.x(), layerOrigin.y());
         p->concatCTM(transform.toAffineTransform());
         
-        LayoutRect filterBounds = LayoutRect(0, 0, size().width(), size().height());
-        p->drawImageBuffer(m_filter->output(), renderer()->style()->colorSpace(), filterBounds, CompositeSourceOver);
+        p->drawImageBuffer(m_filter->output(), renderer()->style()->colorSpace(), LayoutRect(m_filter->outputRect()), CompositeSourceOver);
         return;
     }
 #endif
index 0d0b9e3..91b95b2 100644 (file)
@@ -63,7 +63,7 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
-static bool hasBorderOutlineOrShadow(const RenderStyle*);
+static bool hasBoxDecorations(const RenderStyle*);
 static bool hasBoxDecorationsOrBackground(const RenderObject*);
 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
 static LayoutRect clipBox(RenderBox* renderer);
@@ -743,19 +743,19 @@ float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
     return finalOpacity;
 }
 
-static bool hasBorderOutlineOrShadow(const RenderStyle* style)
+static bool hasBoxDecorations(const RenderStyle* style)
 {
-    return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow();
+    return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
 }
 
 static bool hasBoxDecorationsOrBackground(const RenderObject* renderer)
 {
-    return hasBorderOutlineOrShadow(renderer->style()) || renderer->hasBackground();
+    return hasBoxDecorations(renderer->style()) || renderer->hasBackground();
 }
 
 static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
 {
-    return hasBorderOutlineOrShadow(style) || style->hasBackgroundImage();
+    return hasBoxDecorations(style) || style->hasBackgroundImage();
 }
 
 bool RenderLayerBacking::rendererHasBackground() const
index f2ecfba..5187179 100644 (file)
@@ -88,7 +88,7 @@ void RenderReplaced::layout()
     computeLogicalHeight();
 
     m_overflow.clear();
-    addBoxShadowAndBorderOverflow();
+    addVisualEffectOverflow();
     updateLayerTransform();
     
     repainter.repaintAfterLayout();
index 07c8de9..45eff69 100644 (file)
@@ -399,6 +399,23 @@ public:
         return getImageOutsets(maskBoxImage(), top, right, bottom, left);
     }
 
+#if ENABLE(CSS_FILTERS)
+    void getFilterOutsets(LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left, const LayoutSize& borderBoxSize) const
+    {
+        if (hasFilter())
+            filter().getOutsets(top, right, bottom, left, borderBoxSize);
+        else {
+            top = 0;
+            right = 0;
+            bottom = 0;
+            left = 0;
+        }
+    }
+    bool hasFilterOutsets() const { return hasFilter() && filter().hasOutsets(); }
+#else
+    bool hasFilterOutsets() const { return false; }
+#endif
+
     Order rtlOrdering() const { return static_cast<Order>(inherited_flags.m_rtlOrdering); }
     void setRTLOrdering(Order o) { inherited_flags.m_rtlOrdering = o; }
 
index edc7cfd..e55b25b 100644 (file)
@@ -26,6 +26,8 @@
 #include "config.h"
 #include "StyleFilterData.h"
 
+#include "FEGaussianBlur.h"
+
 #if ENABLE(CSS_FILTERS)
 
 #include "RenderStyle.h"
index 7d72cf5..df68a6b 100644 (file)
@@ -52,7 +52,10 @@ void FEImage::determineAbsolutePaintRect()
     FloatRect srcRect(FloatPoint(), m_image->size());
     FloatRect paintRect(m_absoluteSubregion);
     m_preserveAspectRatio.transformRect(paintRect, srcRect);
-    paintRect.intersect(maxEffectRect());
+    if (clipsToBounds())
+        paintRect.intersect(maxEffectRect());
+    else
+        paintRect.unite(maxEffectRect());
     setAbsolutePaintRect(enclosingIntRect(paintRect));
 }