1 /*
2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #include "config.h"
22
23 #if ENABLE(SVG) && ENABLE(FILTERS)
24 #include "SVGFETurbulenceElement.h"
25
26 #include "Attribute.h"
27 #include "SVGNames.h"
28 #include "SVGParserUtilities.h"
29
30 namespace WebCore {
31
32 // Animated property definitions
DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFETurbulenceElement,SVGNames::baseFrequencyAttr,baseFrequencyXIdentifier (),BaseFrequencyX,baseFrequencyX)33 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFETurbulenceElement, SVGNames::baseFrequencyAttr, baseFrequencyXIdentifier(), BaseFrequencyX, baseFrequencyX)
34 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFETurbulenceElement, SVGNames::baseFrequencyAttr, baseFrequencyYIdentifier(), BaseFrequencyY, baseFrequencyY)
35 DEFINE_ANIMATED_INTEGER(SVGFETurbulenceElement, SVGNames::numOctavesAttr, NumOctaves, numOctaves)
36 DEFINE_ANIMATED_NUMBER(SVGFETurbulenceElement, SVGNames::seedAttr, Seed, seed)
37 DEFINE_ANIMATED_ENUMERATION(SVGFETurbulenceElement, SVGNames::stitchTilesAttr, StitchTiles, stitchTiles)
38 DEFINE_ANIMATED_ENUMERATION(SVGFETurbulenceElement, SVGNames::typeAttr, Type, type)
39
40 inline SVGFETurbulenceElement::SVGFETurbulenceElement(const QualifiedName& tagName, Document* document)
41 : SVGFilterPrimitiveStandardAttributes(tagName, document)
42 , m_numOctaves(1)
43 , m_stitchTiles(SVG_STITCHTYPE_NOSTITCH)
44 , m_type(FETURBULENCE_TYPE_TURBULENCE)
45 {
46 }
47
create(const QualifiedName & tagName,Document * document)48 PassRefPtr<SVGFETurbulenceElement> SVGFETurbulenceElement::create(const QualifiedName& tagName, Document* document)
49 {
50 return adoptRef(new SVGFETurbulenceElement(tagName, document));
51 }
52
baseFrequencyXIdentifier()53 const AtomicString& SVGFETurbulenceElement::baseFrequencyXIdentifier()
54 {
55 DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGBaseFrequencyX"));
56 return s_identifier;
57 }
58
baseFrequencyYIdentifier()59 const AtomicString& SVGFETurbulenceElement::baseFrequencyYIdentifier()
60 {
61 DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGBaseFrequencyY"));
62 return s_identifier;
63 }
64
parseMappedAttribute(Attribute * attr)65 void SVGFETurbulenceElement::parseMappedAttribute(Attribute* attr)
66 {
67 const String& value = attr->value();
68 if (attr->name() == SVGNames::typeAttr) {
69 if (value == "fractalNoise")
70 setTypeBaseValue(FETURBULENCE_TYPE_FRACTALNOISE);
71 else if (value == "turbulence")
72 setTypeBaseValue(FETURBULENCE_TYPE_TURBULENCE);
73 } else if (attr->name() == SVGNames::stitchTilesAttr) {
74 if (value == "stitch")
75 setStitchTilesBaseValue(SVG_STITCHTYPE_STITCH);
76 else if (value == "noStitch")
77 setStitchTilesBaseValue(SVG_STITCHTYPE_NOSTITCH);
78 } else if (attr->name() == SVGNames::baseFrequencyAttr) {
79 float x, y;
80 if (parseNumberOptionalNumber(value, x, y)) {
81 setBaseFrequencyXBaseValue(x);
82 setBaseFrequencyYBaseValue(y);
83 }
84 } else if (attr->name() == SVGNames::seedAttr)
85 setSeedBaseValue(value.toFloat());
86 else if (attr->name() == SVGNames::numOctavesAttr)
87 setNumOctavesBaseValue(value.toUIntStrict());
88 else
89 SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
90 }
91
setFilterEffectAttribute(FilterEffect * effect,const QualifiedName & attrName)92 bool SVGFETurbulenceElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
93 {
94 FETurbulence* turbulence = static_cast<FETurbulence*>(effect);
95 if (attrName == SVGNames::typeAttr)
96 return turbulence->setType(static_cast<TurbulenceType>(type()));
97 if (attrName == SVGNames::stitchTilesAttr)
98 return turbulence->setStitchTiles(stitchTiles());
99 if (attrName == SVGNames::baseFrequencyAttr)
100 return (turbulence->setBaseFrequencyX(baseFrequencyX()) || turbulence->setBaseFrequencyY(baseFrequencyY()));
101 if (attrName == SVGNames::seedAttr)
102 return turbulence->setSeed(seed());
103 if (attrName == SVGNames::numOctavesAttr)
104 return turbulence->setNumOctaves(numOctaves());
105
106 ASSERT_NOT_REACHED();
107 return false;
108 }
109
svgAttributeChanged(const QualifiedName & attrName)110 void SVGFETurbulenceElement::svgAttributeChanged(const QualifiedName& attrName)
111 {
112 SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
113
114 if (attrName == SVGNames::baseFrequencyAttr
115 || attrName == SVGNames::numOctavesAttr
116 || attrName == SVGNames::seedAttr
117 || attrName == SVGNames::stitchTilesAttr
118 || attrName == SVGNames::typeAttr)
119 primitiveAttributeChanged(attrName);
120 }
121
synchronizeProperty(const QualifiedName & attrName)122 void SVGFETurbulenceElement::synchronizeProperty(const QualifiedName& attrName)
123 {
124 SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
125
126 if (attrName == anyQName()) {
127 synchronizeType();
128 synchronizeStitchTiles();
129 synchronizeBaseFrequencyX();
130 synchronizeBaseFrequencyY();
131 synchronizeSeed();
132 synchronizeNumOctaves();
133 return;
134 }
135
136 if (attrName == SVGNames::typeAttr)
137 synchronizeType();
138 else if (attrName == SVGNames::stitchTilesAttr)
139 synchronizeStitchTiles();
140 else if (attrName == SVGNames::baseFrequencyAttr) {
141 synchronizeBaseFrequencyX();
142 synchronizeBaseFrequencyY();
143 } else if (attrName == SVGNames::seedAttr)
144 synchronizeSeed();
145 else if (attrName == SVGNames::numOctavesAttr)
146 synchronizeNumOctaves();
147 }
148
attributeToPropertyTypeMap()149 AttributeToPropertyTypeMap& SVGFETurbulenceElement::attributeToPropertyTypeMap()
150 {
151 DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ());
152 return s_attributeToPropertyTypeMap;
153 }
154
fillAttributeToPropertyTypeMap()155 void SVGFETurbulenceElement::fillAttributeToPropertyTypeMap()
156 {
157 AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap();
158
159 SVGFilterPrimitiveStandardAttributes::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap);
160 attributeToPropertyTypeMap.set(SVGNames::baseFrequencyAttr, AnimatedNumberOptionalNumber);
161 attributeToPropertyTypeMap.set(SVGNames::numOctavesAttr, AnimatedInteger);
162 attributeToPropertyTypeMap.set(SVGNames::seedAttr, AnimatedNumber);
163 attributeToPropertyTypeMap.set(SVGNames::stitchTilesAttr, AnimatedEnumeration);
164 attributeToPropertyTypeMap.set(SVGNames::typeAttr, AnimatedEnumeration);
165 }
166
build(SVGFilterBuilder *,Filter * filter)167 PassRefPtr<FilterEffect> SVGFETurbulenceElement::build(SVGFilterBuilder*, Filter* filter)
168 {
169 if (baseFrequencyX() < 0 || baseFrequencyY() < 0)
170 return 0;
171
172 return FETurbulence::create(filter, static_cast<TurbulenceType>(type()), baseFrequencyX(),
173 baseFrequencyY(), numOctaves(), seed(), stitchTiles() == SVG_STITCHTYPE_STITCH);
174 }
175
176 }
177
178 #endif // ENABLE(SVG)
179