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);
}