Title: [154954] trunk
Revision
154954
Author
[email protected]
Date
2013-09-02 08:03:57 -0700 (Mon, 02 Sep 2013)

Log Message

Use edgeMode=duplicate for blurring on filter() function
https://bugs.webkit.org/show_bug.cgi?id=120590

Reviewed by Antti Koivisto.

Source/WebCore:

Filters on the CSS Image function filter() are not allowed to extend the
dimension of the input image. This causes weird results on blurring an image,
where the fading on the edges is clipped at the half of the fading.
We shouldn't fade edges at all and use the edgeMode=duplicate instead.
This will duplicate the pixel value on the nearest edge of the input image
instead of taking transparent black and results in nice blurred images with
sharp edges.

Spec: http://dev.w3.org/fxtf/filters/#blurEquivalent

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

* css/CSSFilterImageValue.cpp: Pass consumer information to the renderer.
(WebCore::CSSFilterImageValue::image):
* rendering/FilterEffectRenderer.cpp: Set edgeMode for feGaussianBlur to
    'duplicate' or 'none' depending on the consumer.
(WebCore::FilterEffectRenderer::build):
* rendering/FilterEffectRenderer.h: Add enumeration to differ between the
    different consumers of the renderer.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::updateOrRemoveFilterEffectRenderer):  Pass consumer
    information to the renderer.

LayoutTests:

Added test to check that filter(<image>, blur(<value>)) takes
the edgeMode 'duplicate' instead of none.

* fast/filter-image/filter-image-blur-expected.html: Added.
* fast/filter-image/filter-image-blur.html: Added.
* fast/filter-image/resources/svg-blur.svg: Added.
* fast/filter-image/resources/svg-noblur.svg: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (154953 => 154954)


--- trunk/LayoutTests/ChangeLog	2013-09-02 14:40:54 UTC (rev 154953)
+++ trunk/LayoutTests/ChangeLog	2013-09-02 15:03:57 UTC (rev 154954)
@@ -1,3 +1,18 @@
+2013-09-02  Dirk Schulze  <[email protected]>
+
+        Use edgeMode=duplicate for blurring on filter() function
+        https://bugs.webkit.org/show_bug.cgi?id=120590
+
+        Reviewed by Antti Koivisto.
+
+        Added test to check that filter(<image>, blur(<value>)) takes
+        the edgeMode 'duplicate' instead of none.
+
+        * fast/filter-image/filter-image-blur-expected.html: Added.
+        * fast/filter-image/filter-image-blur.html: Added.
+        * fast/filter-image/resources/svg-blur.svg: Added.
+        * fast/filter-image/resources/svg-noblur.svg: Added.
+
 2013-09-02  Gabor Abraham <[email protected]>
 
         [Qt] Unreviewed gardening.

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


--- trunk/LayoutTests/fast/filter-image/filter-image-blur-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/filter-image/filter-image-blur-expected.html	2013-09-02 15:03:57 UTC (rev 154954)
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style>
+    div {
+      width: 200px;
+      height: 100px;
+      background-image: url(resources/svg-blur.svg);
+    }
+  </style>
+</head>
+<body>
+<div>
+</div>
+</body>
+</html>

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


--- trunk/LayoutTests/fast/filter-image/filter-image-blur.html	                        (rev 0)
+++ trunk/LayoutTests/fast/filter-image/filter-image-blur.html	2013-09-02 15:03:57 UTC (rev 154954)
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style>
+    div {
+      width: 200px;
+      height: 100px;
+      background-image: -webkit-filter(url(resources/svg-noblur.svg), blur(3px));
+    }
+  </style>
+</head>
+<body>
+<div>
+</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/filter-image/resources/svg-blur.svg (0 => 154954)


--- trunk/LayoutTests/fast/filter-image/resources/svg-blur.svg	                        (rev 0)
+++ trunk/LayoutTests/fast/filter-image/resources/svg-blur.svg	2013-09-02 15:03:57 UTC (rev 154954)
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
+<defs>
+<filter id="blur">
+<feGaussianBlur stdDeviation="3" edgeMode="duplicate" color-interpolation-filters="sRGB"/>
+</filter>
+</defs>
+<g filter="url(#blur)">
+<rect x="-30" y="-30" width="260" height="260" fill="green"/>
+<rect x="50" y="50" width="100" height="100" fill="blue"/>
+</g>
+</svg>
\ No newline at end of file

Added: trunk/LayoutTests/fast/filter-image/resources/svg-noblur.svg (0 => 154954)


--- trunk/LayoutTests/fast/filter-image/resources/svg-noblur.svg	                        (rev 0)
+++ trunk/LayoutTests/fast/filter-image/resources/svg-noblur.svg	2013-09-02 15:03:57 UTC (rev 154954)
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
+<rect width="200" height="200" fill="green"/>
+<rect x="50" y="50" width="100" height="100" fill="blue"/>
+</svg>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (154953 => 154954)


--- trunk/Source/WebCore/ChangeLog	2013-09-02 14:40:54 UTC (rev 154953)
+++ trunk/Source/WebCore/ChangeLog	2013-09-02 15:03:57 UTC (rev 154954)
@@ -1,3 +1,33 @@
+2013-09-02  Dirk Schulze  <[email protected]>
+
+        Use edgeMode=duplicate for blurring on filter() function
+        https://bugs.webkit.org/show_bug.cgi?id=120590
+
+        Reviewed by Antti Koivisto.
+
+        Filters on the CSS Image function filter() are not allowed to extend the
+        dimension of the input image. This causes weird results on blurring an image,
+        where the fading on the edges is clipped at the half of the fading.
+        We shouldn't fade edges at all and use the edgeMode=duplicate instead.
+        This will duplicate the pixel value on the nearest edge of the input image
+        instead of taking transparent black and results in nice blurred images with
+        sharp edges.
+
+        Spec: http://dev.w3.org/fxtf/filters/#blurEquivalent
+
+        Test: fast/filter-image/filter-image-blur.html
+
+        * css/CSSFilterImageValue.cpp: Pass consumer information to the renderer.
+        (WebCore::CSSFilterImageValue::image):
+        * rendering/FilterEffectRenderer.cpp: Set edgeMode for feGaussianBlur to
+            'duplicate' or 'none' depending on the consumer.
+        (WebCore::FilterEffectRenderer::build):
+        * rendering/FilterEffectRenderer.h: Add enumeration to differ between the 
+            different consumers of the renderer.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::updateOrRemoveFilterEffectRenderer):  Pass consumer
+            information to the renderer.
+
 2013-09-01  Dirk Schulze  <[email protected]>
 
         Add 'edgeMode' attribute to SVGFEGaussianBlur

Modified: trunk/Source/WebCore/css/CSSFilterImageValue.cpp (154953 => 154954)


--- trunk/Source/WebCore/css/CSSFilterImageValue.cpp	2013-09-02 14:40:54 UTC (rev 154953)
+++ trunk/Source/WebCore/css/CSSFilterImageValue.cpp	2013-09-02 15:03:57 UTC (rev 154954)
@@ -123,7 +123,7 @@
     filterRenderer->setSourceImageRect(FloatRect(FloatPoint(), size));
     filterRenderer->setFilterRegion(FloatRect(FloatPoint(), size));
     // FIXME: SVG Filter don't work at the moment.
-    if (!filterRenderer->build(0, m_filterOperations, true))
+    if (!filterRenderer->build(0, m_filterOperations, FilterFunction))
         return Image::nullImage();
     filterRenderer->apply();
 

Modified: trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp (154953 => 154954)


--- trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp	2013-09-02 14:40:54 UTC (rev 154953)
+++ trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp	2013-09-02 15:03:57 UTC (rev 154954)
@@ -179,7 +179,7 @@
 #endif
 }
 
-bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations& operations, bool clipsToBounds)
+bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations& operations, FilterConsumer consumer)
 {
 #if ENABLE(CSS_SHADERS)
     m_hasCustomShaderFilter = false;
@@ -326,7 +326,7 @@
         case FilterOperation::BLUR: {
             BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation);
             float stdDeviation = floatValueForLength(blurOperation->stdDeviation(), 0);
-            effect = FEGaussianBlur::create(this, stdDeviation, stdDeviation, EDGEMODE_NONE);
+            effect = FEGaussianBlur::create(this, stdDeviation, stdDeviation, consumer == FilterProperty ? EDGEMODE_NONE : EDGEMODE_DUPLICATE);
             break;
         }
         case FilterOperation::DROP_SHADOW: {
@@ -357,7 +357,7 @@
         if (effect) {
             // Unlike SVG Filters and CSSFilterImages, filter functions on the filter
             // property applied here should not clip to their primitive subregions.
-            effect->setClipsToBounds(clipsToBounds);
+            effect->setClipsToBounds(consumer == FilterFunction);
             effect->setOperatingColorSpace(ColorSpaceDeviceRGB);
             
             if (filterOperation->getOperationType() != FilterOperation::REFERENCE) {

Modified: trunk/Source/WebCore/rendering/FilterEffectRenderer.h (154953 => 154954)


--- trunk/Source/WebCore/rendering/FilterEffectRenderer.h	2013-09-02 14:40:54 UTC (rev 154953)
+++ trunk/Source/WebCore/rendering/FilterEffectRenderer.h	2013-09-02 15:03:57 UTC (rev 154954)
@@ -53,6 +53,11 @@
 class RenderLayer;
 class RenderObject;
 
+enum FilterConsumer {
+    FilterProperty,
+    FilterFunction
+};
+
 class FilterEffectRendererHelper {
 public:
     FilterEffectRendererHelper(bool haveFilterEffect)
@@ -104,7 +109,7 @@
     GraphicsContext* inputContext();
     ImageBuffer* output() const { return lastEffect()->asImageBuffer(); }
 
-    bool build(RenderObject* renderer, const FilterOperations&, bool clipsToBounds = false);
+    bool build(RenderObject* renderer, const FilterOperations&, FilterConsumer);
     PassRefPtr<FilterEffect> buildReferenceFilter(RenderObject* renderer, PassRefPtr<FilterEffect> previousEffect, ReferenceFilterOperation*);
     bool updateBackingStoreRect(const FloatRect& filterRect);
     void allocateBackingStoreIfNeeded();

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (154953 => 154954)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2013-09-02 14:40:54 UTC (rev 154953)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2013-09-02 15:03:57 UTC (rev 154954)
@@ -6330,7 +6330,7 @@
 
     // If the filter fails to build, remove it from the layer. It will still attempt to
     // go through regular processing (e.g. compositing), but never apply anything.
-    if (!filterInfo->renderer()->build(&renderer(), computeFilterOperations(renderer().style())))
+    if (!filterInfo->renderer()->build(&renderer(), computeFilterOperations(renderer().style()), FilterProperty))
         filterInfo->setRenderer(0);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to