Changeset 154948 in webkit
- Timestamp:
- Sep 1, 2013 9:53:46 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 9 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r154944 r154948 1 2013-09-01 Dirk Schulze <krit@webkit.org> 2 3 Add edgeMode attribtue. 4 5 Add 'edgeMode' attribute to SVGFEGaussianBlur 6 https://bugs.webkit.org/show_bug.cgi?id=120582 7 8 Added DOM and SVGDOM tests for the attribute 'edgeMode'. 9 Also added a reftest to test edgeMode='duplicate'. 10 11 Reviewed by Rob Buis. 12 13 * platform/mac/svg/dynamic-updates/SVGFEGaussianBlurElement-svgdom-edgeMode-prop-expected.png: Added. 14 * svg/dynamic-updates/SVGFEGaussianBlurElement-dom-edgeMode-attr-expected.txt: Added. 15 * svg/dynamic-updates/SVGFEGaussianBlurElement-dom-edgeMode-attr.html: Added. 16 * svg/dynamic-updates/SVGFEGaussianBlurElement-svgdom-edgeMode-prop-expected.txt: Added. 17 * svg/dynamic-updates/SVGFEGaussianBlurElement-svgdom-edgeMode-prop.html: Added. 18 * svg/dynamic-updates/script-tests/SVGFEGaussianBlurElement-dom-edgeMode-attr.js: Added. 19 (repaintTest): 20 * svg/dynamic-updates/script-tests/SVGFEGaussianBlurElement-svgdom-edgeMode-prop.js: Added. 21 (repaintTest): 22 * svg/filters/svg-gaussianblur-edgeMode-duplicate-expected.svg: Added. 23 * svg/filters/svg-gaussianblur-edgeMode-duplicate.svg: Added. 24 1 25 2013-09-01 Xabier Rodriguez Calvar <calvaris@igalia.com> 2 26 -
trunk/Source/WebCore/ChangeLog
r154947 r154948 1 2013-09-01 Dirk Schulze <krit@webkit.org> 2 3 Add 'edgeMode' attribute to SVGFEGaussianBlur 4 https://bugs.webkit.org/show_bug.cgi?id=120582 5 6 Add 'edgeMode' attribute to the SVGFEGaussianBlur element. This attribute 7 allows users to define the behavior on edges with the values 'none' where 8 pixel values outside the input image are treated as transparent black. (The 9 current blurring behavior.) 'duplicate' which repeats the values on the 10 nearest edge and 'warp', which takes the pixel of the opposite site of 11 the input image. 12 Beside the attribute, this patch implements the behavior of 'duplicate'. 13 14 http://dev.w3.org/fxtf/filters/#feGaussianBlurEdgeModeAttribute 15 16 Reviewed by Rob Buis. 17 18 Tests: svg/dynamic-updates/SVGFEGaussianBlurElement-dom-edgeMode-attr.html 19 svg/dynamic-updates/SVGFEGaussianBlurElement-svgdom-edgeMode-prop.html 20 svg/filters/svg-gaussianblur-edgeMode-duplicate-expected.svg 21 svg/filters/svg-gaussianblur-edgeMode-duplicate.svg 22 23 * platform/graphics/filters/FEGaussianBlur.cpp: 24 (WebCore::FEGaussianBlur::FEGaussianBlur): 25 (WebCore::FEGaussianBlur::create): 26 (WebCore::FEGaussianBlur::edgeMode): 27 (WebCore::FEGaussianBlur::setEdgeMode): 28 (WebCore::boxBlur): 29 (WebCore::FEGaussianBlur::platformApplyGeneric): 30 (WebCore::FEGaussianBlur::determineAbsolutePaintRect): 31 * platform/graphics/filters/FEGaussianBlur.h: 32 * rendering/FilterEffectRenderer.cpp: 33 (WebCore::FilterEffectRenderer::build): 34 * svg/SVGFEGaussianBlurElement.cpp: 35 (WebCore::SVGFEGaussianBlurElement::SVGFEGaussianBlurElement): 36 (WebCore::SVGFEGaussianBlurElement::isSupportedAttribute): 37 (WebCore::SVGFEGaussianBlurElement::parseAttribute): 38 (WebCore::SVGFEGaussianBlurElement::svgAttributeChanged): 39 (WebCore::SVGFEGaussianBlurElement::build): 40 * svg/SVGFEGaussianBlurElement.h: 41 * svg/SVGFEGaussianBlurElement.idl: 42 1 43 2013-09-01 Andreas Kling <akling@apple.com> 2 44 -
trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
r154127 r154948 51 51 namespace WebCore { 52 52 53 FEGaussianBlur::FEGaussianBlur(Filter* filter, float x, float y )53 FEGaussianBlur::FEGaussianBlur(Filter* filter, float x, float y, EdgeModeType edgeMode) 54 54 : FilterEffect(filter) 55 55 , m_stdX(x) 56 56 , m_stdY(y) 57 { 58 } 59 60 PassRefPtr<FEGaussianBlur> FEGaussianBlur::create(Filter* filter, float x, float y) 61 { 62 return adoptRef(new FEGaussianBlur(filter, x, y)); 57 , m_edgeMode(edgeMode) 58 { 59 } 60 61 PassRefPtr<FEGaussianBlur> FEGaussianBlur::create(Filter* filter, float x, float y, EdgeModeType edgeMode) 62 { 63 return adoptRef(new FEGaussianBlur(filter, x, y, edgeMode)); 63 64 } 64 65 … … 83 84 } 84 85 86 EdgeModeType FEGaussianBlur::edgeMode() const 87 { 88 return m_edgeMode; 89 } 90 91 void FEGaussianBlur::setEdgeMode(EdgeModeType edgeMode) 92 { 93 m_edgeMode = edgeMode; 94 } 95 85 96 inline void boxBlur(Uint8ClampedArray* srcPixelArray, Uint8ClampedArray* dstPixelArray, 86 unsigned dx, int dxLeft, int dxRight, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage)97 unsigned dx, int dxLeft, int dxRight, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage, EdgeModeType edgeMode) 87 98 { 88 99 for (int y = 0; y < effectHeight; ++y) { … … 90 101 for (int channel = 3; channel >= 0; --channel) { 91 102 int sum = 0; 92 // Fill the kernel 93 int maxKernelSize = min(dxRight, effectWidth); 94 for (int i = 0; i < maxKernelSize; ++i) 95 sum += srcPixelArray->item(line + i * stride + channel); 96 97 // Blurring 98 for (int x = 0; x < effectWidth; ++x) { 99 int pixelByteOffset = line + x * stride + channel; 100 dstPixelArray->set(pixelByteOffset, static_cast<unsigned char>(sum / dx)); 101 if (x >= dxLeft) 102 sum -= srcPixelArray->item(pixelByteOffset - dxLeft * stride); 103 if (x + dxRight < effectWidth) 104 sum += srcPixelArray->item(pixelByteOffset + dxRight * stride); 103 // The code for edgeMode='none' is the common case and highly optimized. 104 // Furthermore, this code path affects more than just the input area. 105 if (edgeMode == EDGEMODE_NONE) { 106 // Fill the kernel 107 int maxKernelSize = min(dxRight, effectWidth); 108 for (int i = 0; i < maxKernelSize; ++i) 109 sum += srcPixelArray->item(line + i * stride + channel); 110 111 // Blurring 112 for (int x = 0; x < effectWidth; ++x) { 113 int pixelByteOffset = line + x * stride + channel; 114 dstPixelArray->set(pixelByteOffset, static_cast<unsigned char>(sum / dx)); 115 // Shift kernel. 116 if (x >= dxLeft) 117 sum -= srcPixelArray->item(pixelByteOffset - dxLeft * stride); 118 if (x + dxRight < effectWidth) 119 sum += srcPixelArray->item(pixelByteOffset + dxRight * stride); 120 } 121 } else { 122 // FIXME: Add support for 'wrap' here. 123 // Get edge values for edgeMode 'duplicate'. 124 int edgeValueLeft = srcPixelArray->item(line + channel); 125 int edgeValueRight = srcPixelArray->item(line + (effectWidth - 1) * stride + channel); 126 // Fill the kernel 127 for (int i = dxLeft * -1; i < dxRight; ++i) { 128 if (i < 0) 129 sum += edgeValueLeft; 130 else if (i >= effectWidth) 131 sum += edgeValueRight; 132 else 133 sum += srcPixelArray->item(line + i * stride + channel); 134 } 135 // Blurring 136 for (int x = 0; x < effectWidth; ++x) { 137 int pixelByteOffset = line + x * stride + channel; 138 dstPixelArray->set(pixelByteOffset, static_cast<unsigned char>(sum / dx)); 139 // Shift kernel. 140 if (x < dxLeft) 141 sum -= edgeValueLeft; 142 else 143 sum -= srcPixelArray->item(pixelByteOffset - dxLeft * stride); 144 if (x + dxRight >= effectWidth) 145 sum += edgeValueRight; 146 else 147 sum += srcPixelArray->item(pixelByteOffset + dxRight * stride); 148 } 105 149 } 106 150 if (alphaImage) // Source image is black, it just has different alpha values … … 127 171 boxBlurNEON(src, dst, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height()); 128 172 else 129 boxBlur(src, dst, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height(), true );173 boxBlur(src, dst, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height(), true, m_edgeMode); 130 174 #else 131 boxBlur(src, dst, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height(), isAlphaImage() );175 boxBlur(src, dst, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height(), isAlphaImage(), m_edgeMode); 132 176 #endif 133 177 swap(src, dst); … … 140 184 boxBlurNEON(src, dst, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width()); 141 185 else 142 boxBlur(src, dst, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width(), true );186 boxBlur(src, dst, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width(), true, m_edgeMode); 143 187 #else 144 boxBlur(src, dst, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width(), isAlphaImage() );188 boxBlur(src, dst, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width(), isAlphaImage(), m_edgeMode); 145 189 #endif 146 190 swap(src, dst); … … 265 309 266 310 FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect(); 311 // Edge modes other than 'none' do not inflate the affected paint rect. 312 if (m_edgeMode != EDGEMODE_NONE) { 313 setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); 314 return; 315 } 267 316 268 317 // We take the half kernel size and multiply it with three, because we run box blur three times. -
trunk/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h
r149193 r154948 24 24 25 25 #if ENABLE(FILTERS) 26 #include "FEConvolveMatrix.h" 27 #include "Filter.h" 26 28 #include "FilterEffect.h" 27 #include "Filter.h"28 29 29 30 namespace WebCore { … … 31 32 class FEGaussianBlur : public FilterEffect { 32 33 public: 33 static PassRefPtr<FEGaussianBlur> create(Filter*, float, float );34 static PassRefPtr<FEGaussianBlur> create(Filter*, float, float, EdgeModeType); 34 35 35 36 float stdDeviationX() const; … … 38 39 float stdDeviationY() const; 39 40 void setStdDeviationY(float); 41 42 EdgeModeType edgeMode() const; 43 void setEdgeMode(EdgeModeType); 40 44 41 45 static float calculateStdDeviation(float); … … 68 72 static void platformApplyWorker(PlatformApplyParameters*); 69 73 70 FEGaussianBlur(Filter*, float, float );74 FEGaussianBlur(Filter*, float, float, EdgeModeType); 71 75 72 76 static inline void kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& dRight); … … 77 81 float m_stdX; 78 82 float m_stdY; 83 EdgeModeType m_edgeMode; 79 84 }; 80 85 -
trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp
r154928 r154948 327 327 BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation); 328 328 float stdDeviation = floatValueForLength(blurOperation->stdDeviation(), 0); 329 effect = FEGaussianBlur::create(this, stdDeviation, stdDeviation );329 effect = FEGaussianBlur::create(this, stdDeviation, stdDeviation, EDGEMODE_NONE); 330 330 break; 331 331 } -
trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp
r151800 r154948 37 37 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEGaussianBlurElement, SVGNames::stdDeviationAttr, stdDeviationXIdentifier(), StdDeviationX, stdDeviationX) 38 38 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEGaussianBlurElement, SVGNames::stdDeviationAttr, stdDeviationYIdentifier(), StdDeviationY, stdDeviationY) 39 DEFINE_ANIMATED_ENUMERATION(SVGFEGaussianBlurElement, SVGNames::edgeModeAttr, EdgeMode, edgeMode, EdgeModeType) 39 40 40 41 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEGaussianBlurElement) … … 42 43 REGISTER_LOCAL_ANIMATED_PROPERTY(stdDeviationX) 43 44 REGISTER_LOCAL_ANIMATED_PROPERTY(stdDeviationY) 45 REGISTER_LOCAL_ANIMATED_PROPERTY(edgeMode) 44 46 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes) 45 47 END_REGISTER_ANIMATED_PROPERTIES … … 47 49 inline SVGFEGaussianBlurElement::SVGFEGaussianBlurElement(const QualifiedName& tagName, Document* document) 48 50 : SVGFilterPrimitiveStandardAttributes(tagName, document) 51 , m_edgeMode(EDGEMODE_NONE) 49 52 { 50 53 ASSERT(hasTagName(SVGNames::feGaussianBlurTag)); … … 82 85 supportedAttributes.add(SVGNames::inAttr); 83 86 supportedAttributes.add(SVGNames::stdDeviationAttr); 87 supportedAttributes.add(SVGNames::edgeModeAttr); 84 88 } 85 89 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); … … 107 111 } 108 112 113 if (name == SVGNames::edgeModeAttr) { 114 EdgeModeType propertyValue = SVGPropertyTraits<EdgeModeType>::fromString(value); 115 if (propertyValue > 0) 116 setEdgeModeBaseValue(propertyValue); 117 else 118 document().accessSVGExtensions()->reportWarning( 119 "feGaussianBlur: problem parsing edgeMode=\"" + value 120 + "\". Filtered element will not be displayed."); 121 return; 122 } 123 109 124 ASSERT_NOT_REACHED(); 110 125 } … … 119 134 SVGElementInstance::InvalidationGuard invalidationGuard(this); 120 135 121 if (attrName == SVGNames::inAttr || attrName == SVGNames::stdDeviationAttr) { 136 if (attrName == SVGNames::inAttr 137 || attrName == SVGNames::stdDeviationAttr 138 || attrName == SVGNames::edgeModeAttr) { 122 139 invalidate(); 123 140 return; … … 137 154 return 0; 138 155 139 RefPtr<FilterEffect> effect = FEGaussianBlur::create(filter, stdDeviationX(), stdDeviationY() );156 RefPtr<FilterEffect> effect = FEGaussianBlur::create(filter, stdDeviationX(), stdDeviationY(), edgeMode()); 140 157 effect->inputEffects().append(input1); 141 158 return effect.release(); -
trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.h
r149960 r154948 24 24 #if ENABLE(SVG) && ENABLE(FILTERS) 25 25 #include "FEGaussianBlur.h" 26 #include "SVGAnimatedEnumeration.h" 26 27 #include "SVGAnimatedNumber.h" 28 #include "SVGFEConvolveMatrixElement.h" 27 29 #include "SVGFilterPrimitiveStandardAttributes.h" 28 30 … … 50 52 DECLARE_ANIMATED_NUMBER(StdDeviationX, stdDeviationX) 51 53 DECLARE_ANIMATED_NUMBER(StdDeviationY, stdDeviationY) 54 DECLARE_ANIMATED_ENUMERATION(EdgeMode, edgeMode, EdgeModeType) 52 55 END_DECLARE_ANIMATED_PROPERTIES 53 56 }; -
trunk/Source/WebCore/svg/SVGFEGaussianBlurElement.idl
r154462 r154948 25 25 26 26 [ 27 Conditional=SVG&FILTERS 27 Conditional=SVG&FILTERS, 28 DoNotCheckConstants 28 29 ] interface SVGFEGaussianBlurElement : SVGElement { 30 // Edge Mode Values 31 const unsigned short SVG_EDGEMODE_UNKNOWN = 0; 32 const unsigned short SVG_EDGEMODE_DUPLICATE = 1; 33 const unsigned short SVG_EDGEMODE_WRAP = 2; 34 const unsigned short SVG_EDGEMODE_NONE = 3; 35 29 36 readonly attribute SVGAnimatedString in1; 30 37 readonly attribute SVGAnimatedNumber stdDeviationX; 31 38 readonly attribute SVGAnimatedNumber stdDeviationY; 39 readonly attribute SVGAnimatedEnumeration edgeMode; 32 40 33 41 void setStdDeviation([Default=Undefined] optional float stdDeviationX,
Note: See TracChangeset
for help on using the changeset viewer.