summaryrefslogtreecommitdiffstats
path: root/WebCore/svg
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/svg')
-rw-r--r--WebCore/svg/SVGClipPathElement.cpp13
-rw-r--r--WebCore/svg/SVGClipPathElement.h1
-rw-r--r--WebCore/svg/SVGElement.cpp24
-rw-r--r--WebCore/svg/SVGElement.h2
-rw-r--r--WebCore/svg/SVGFETurbulenceElement.cpp3
-rw-r--r--WebCore/svg/SVGFilterElement.cpp17
-rw-r--r--WebCore/svg/SVGFilterElement.h2
-rw-r--r--WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp2
-rw-r--r--WebCore/svg/SVGFilterPrimitiveStandardAttributes.h3
-rw-r--r--WebCore/svg/SVGGradientElement.cpp13
-rw-r--r--WebCore/svg/SVGGradientElement.h2
-rw-r--r--WebCore/svg/SVGLinearGradientElement.cpp13
-rw-r--r--WebCore/svg/SVGMarkerElement.cpp19
-rw-r--r--WebCore/svg/SVGMarkerElement.h2
-rw-r--r--WebCore/svg/SVGMaskElement.cpp13
-rw-r--r--WebCore/svg/SVGMaskElement.h1
-rw-r--r--WebCore/svg/SVGParserUtilities.cpp18
-rw-r--r--WebCore/svg/SVGPatternElement.cpp19
-rw-r--r--WebCore/svg/SVGPatternElement.h1
-rw-r--r--WebCore/svg/SVGRadialGradientElement.cpp13
-rw-r--r--WebCore/svg/SVGScriptElement.cpp5
-rw-r--r--WebCore/svg/SVGScriptElement.h2
-rw-r--r--WebCore/svg/SVGStyleElement.cpp32
-rw-r--r--WebCore/svg/SVGStyleElement.h51
-rw-r--r--WebCore/svg/SVGStyledElement.cpp13
-rw-r--r--WebCore/svg/SVGStyledElement.h3
-rw-r--r--WebCore/svg/graphics/filters/SVGFETurbulence.cpp249
-rw-r--r--WebCore/svg/graphics/filters/SVGFETurbulence.h88
28 files changed, 476 insertions, 148 deletions
diff --git a/WebCore/svg/SVGClipPathElement.cpp b/WebCore/svg/SVGClipPathElement.cpp
index c3a514e..5c23031 100644
--- a/WebCore/svg/SVGClipPathElement.cpp
+++ b/WebCore/svg/SVGClipPathElement.cpp
@@ -69,12 +69,16 @@ void SVGClipPathElement::svgAttributeChanged(const QualifiedName& attrName)
{
SVGStyledTransformableElement::svgAttributeChanged(attrName);
+ RenderObject* object = renderer();
+ if (!object)
+ return;
+
if (attrName == SVGNames::clipPathUnitsAttr ||
SVGTests::isKnownAttribute(attrName) ||
SVGLangSpace::isKnownAttribute(attrName) ||
SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
SVGStyledTransformableElement::isKnownAttribute(attrName))
- invalidateResourceClients();
+ object->setNeedsLayout(true);
}
void SVGClipPathElement::synchronizeProperty(const QualifiedName& attrName)
@@ -97,8 +101,11 @@ void SVGClipPathElement::childrenChanged(bool changedByParser, Node* beforeChang
{
SVGStyledTransformableElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!changedByParser)
- invalidateResourceClients();
+ if (changedByParser)
+ return;
+
+ if (RenderObject* object = renderer())
+ object->setNeedsLayout(true);
}
RenderObject* SVGClipPathElement::createRenderer(RenderArena* arena, RenderStyle*)
diff --git a/WebCore/svg/SVGClipPathElement.h b/WebCore/svg/SVGClipPathElement.h
index eb74f72..11b07fb 100644
--- a/WebCore/svg/SVGClipPathElement.h
+++ b/WebCore/svg/SVGClipPathElement.h
@@ -39,6 +39,7 @@ public:
virtual ~SVGClipPathElement();
virtual bool isValid() const { return SVGTests::isValid(); }
+ virtual bool needsPendingResourceHandling() const { return false; }
virtual void parseMappedAttribute(Attribute*);
virtual void svgAttributeChanged(const QualifiedName&);
diff --git a/WebCore/svg/SVGElement.cpp b/WebCore/svg/SVGElement.cpp
index b262e45..0497edf 100644
--- a/WebCore/svg/SVGElement.cpp
+++ b/WebCore/svg/SVGElement.cpp
@@ -278,20 +278,22 @@ bool SVGElement::childShouldCreateRenderer(Node* child) const
void SVGElement::insertedIntoDocument()
{
StyledElement::insertedIntoDocument();
- SVGDocumentExtensions* extensions = document()->accessSVGExtensions();
- String resourceId = getIdAttribute();
- if (extensions->isPendingResource(resourceId)) {
- OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(resourceId));
- if (clients->isEmpty())
- return;
+ if (!needsPendingResourceHandling())
+ return;
- HashSet<SVGStyledElement*>::const_iterator it = clients->begin();
- const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
+ SVGDocumentExtensions* extensions = document()->accessSVGExtensions();
+ String resourceId = getIdAttribute();
+ if (!extensions->isPendingResource(resourceId))
+ return;
+
+ OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(resourceId));
+ if (clients->isEmpty())
+ return;
- for (; it != end; ++it)
- (*it)->buildPendingResource();
- }
+ const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
+ for (HashSet<SVGStyledElement*>::const_iterator it = clients->begin(); it != end; ++it)
+ (*it)->buildPendingResource();
}
void SVGElement::attributeChanged(Attribute* attr, bool preserveDecls)
diff --git a/WebCore/svg/SVGElement.h b/WebCore/svg/SVGElement.h
index 64afe8e..eccf03e 100644
--- a/WebCore/svg/SVGElement.h
+++ b/WebCore/svg/SVGElement.h
@@ -97,6 +97,8 @@ namespace WebCore {
virtual bool isSupported(StringImpl* feature, StringImpl* version) const;
virtual ContainerNode* eventParentNode();
+
+ virtual bool needsPendingResourceHandling() const { return true; }
virtual void buildPendingResource() { }
void mapInstanceToElement(SVGElementInstance*);
diff --git a/WebCore/svg/SVGFETurbulenceElement.cpp b/WebCore/svg/SVGFETurbulenceElement.cpp
index e5b5419..e4987c5 100644
--- a/WebCore/svg/SVGFETurbulenceElement.cpp
+++ b/WebCore/svg/SVGFETurbulenceElement.cpp
@@ -99,6 +99,9 @@ void SVGFETurbulenceElement::synchronizeProperty(const QualifiedName& attrName)
PassRefPtr<FilterEffect> SVGFETurbulenceElement::build(SVGFilterBuilder*)
{
+ if (baseFrequencyX() < 0 || baseFrequencyY() < 0)
+ return 0;
+
return FETurbulence::create(static_cast<TurbulanceType>(type()), baseFrequencyX(),
baseFrequencyY(), numOctaves(), seed(), stitchTiles() == SVG_STITCHTYPE_STITCH);
}
diff --git a/WebCore/svg/SVGFilterElement.cpp b/WebCore/svg/SVGFilterElement.cpp
index 4387e71..0d55bb1 100644
--- a/WebCore/svg/SVGFilterElement.cpp
+++ b/WebCore/svg/SVGFilterElement.cpp
@@ -66,7 +66,9 @@ void SVGFilterElement::setFilterRes(unsigned long filterResX, unsigned long filt
{
setFilterResXBaseValue(filterResX);
setFilterResYBaseValue(filterResY);
- invalidateResourceClients();
+
+ if (RenderObject* object = renderer())
+ object->setNeedsLayout(true);
}
void SVGFilterElement::parseMappedAttribute(Attribute* attr)
@@ -121,6 +123,10 @@ void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName)
updateRelativeLengthsInformation();
}
+ RenderObject* object = renderer();
+ if (!object)
+ return;
+
if (invalidateClients
|| attrName == SVGNames::filterUnitsAttr
|| attrName == SVGNames::primitiveUnitsAttr
@@ -129,7 +135,7 @@ void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName)
|| SVGURIReference::isKnownAttribute(attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
- invalidateResourceClients();
+ object->setNeedsLayout(true);
}
void SVGFilterElement::synchronizeProperty(const QualifiedName& attrName)
@@ -175,8 +181,11 @@ void SVGFilterElement::childrenChanged(bool changedByParser, Node* beforeChange,
{
SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!changedByParser)
- invalidateResourceClients();
+ if (changedByParser)
+ return;
+
+ if (RenderObject* object = renderer())
+ object->setNeedsLayout(true);
}
FloatRect SVGFilterElement::filterBoundingBox(const FloatRect& objectBoundingBox) const
diff --git a/WebCore/svg/SVGFilterElement.h b/WebCore/svg/SVGFilterElement.h
index 7b0192c..cdb2297 100644
--- a/WebCore/svg/SVGFilterElement.h
+++ b/WebCore/svg/SVGFilterElement.h
@@ -43,6 +43,8 @@ public:
SVGFilterElement(const QualifiedName&, Document*);
virtual ~SVGFilterElement();
+ virtual bool needsPendingResourceHandling() const { return false; }
+
void setFilterRes(unsigned long filterResX, unsigned long filterResY);
FloatRect filterBoundingBox(const FloatRect&) const;
diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
index 8e284e6..042d93b 100644
--- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
+++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
@@ -107,7 +107,7 @@ void SVGFilterPrimitiveStandardAttributes::childrenChanged(bool changedByParser,
SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
if (!changedByParser)
- invalidateResourceClients();
+ invalidateFilter();
}
void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(bool primitiveBoundingBoxMode, FilterEffect* filterEffect) const
diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
index 14784a5..19f6f3a 100644
--- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
+++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
@@ -55,7 +55,8 @@ protected:
{
if (!inDocument() || !parentNode()->hasTagName(SVGNames::filterTag))
return;
- static_cast<SVGFilterElement*>(parentNode())->invalidateResourceClients();
+ if (RenderObject* object = parentNode()->renderer())
+ object->setNeedsLayout(true);
}
private:
diff --git a/WebCore/svg/SVGGradientElement.cpp b/WebCore/svg/SVGGradientElement.cpp
index b314674..0d06955 100644
--- a/WebCore/svg/SVGGradientElement.cpp
+++ b/WebCore/svg/SVGGradientElement.cpp
@@ -85,13 +85,17 @@ void SVGGradientElement::svgAttributeChanged(const QualifiedName& attrName)
{
SVGStyledElement::svgAttributeChanged(attrName);
+ RenderObject* object = renderer();
+ if (!object)
+ return;
+
if (attrName == SVGNames::gradientUnitsAttr
|| attrName == SVGNames::gradientTransformAttr
|| attrName == SVGNames::spreadMethodAttr
|| SVGURIReference::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName)
|| SVGStyledElement::isKnownAttribute(attrName))
- invalidateResourceClients();
+ object->setNeedsLayout(true);
}
void SVGGradientElement::synchronizeProperty(const QualifiedName& attrName)
@@ -123,8 +127,11 @@ void SVGGradientElement::childrenChanged(bool changedByParser, Node* beforeChang
{
SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!changedByParser)
- invalidateResourceClients();
+ if (changedByParser)
+ return;
+
+ if (RenderObject* object = renderer())
+ object->setNeedsLayout(true);
}
Vector<Gradient::ColorStop> SVGGradientElement::buildStops()
diff --git a/WebCore/svg/SVGGradientElement.h b/WebCore/svg/SVGGradientElement.h
index 2736ab3..11a13e4 100644
--- a/WebCore/svg/SVGGradientElement.h
+++ b/WebCore/svg/SVGGradientElement.h
@@ -37,6 +37,8 @@ namespace WebCore {
SVGGradientElement(const QualifiedName&, Document*);
virtual ~SVGGradientElement();
+ virtual bool needsPendingResourceHandling() const { return false; }
+
virtual void parseMappedAttribute(Attribute*);
virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
diff --git a/WebCore/svg/SVGLinearGradientElement.cpp b/WebCore/svg/SVGLinearGradientElement.cpp
index d95c084..37f380b 100644
--- a/WebCore/svg/SVGLinearGradientElement.cpp
+++ b/WebCore/svg/SVGLinearGradientElement.cpp
@@ -76,7 +76,12 @@ void SVGLinearGradientElement::svgAttributeChanged(const QualifiedName& attrName
|| attrName == SVGNames::x2Attr
|| attrName == SVGNames::y2Attr) {
updateRelativeLengthsInformation();
- invalidateResourceClients();
+
+ RenderObject* object = renderer();
+ if (!object)
+ return;
+
+ object->setNeedsLayout(true);
}
}
@@ -155,8 +160,10 @@ LinearGradientAttributes SVGLinearGradientElement::collectGradientProperties()
current = static_cast<SVGGradientElement*>(refNode);
// Cycle detection
- if (processedGradients.contains(current))
- return LinearGradientAttributes();
+ if (processedGradients.contains(current)) {
+ current = 0;
+ break;
+ }
isLinear = current->hasTagName(SVGNames::linearGradientTag);
} else
diff --git a/WebCore/svg/SVGMarkerElement.cpp b/WebCore/svg/SVGMarkerElement.cpp
index 01faf21..195e91d 100644
--- a/WebCore/svg/SVGMarkerElement.cpp
+++ b/WebCore/svg/SVGMarkerElement.cpp
@@ -113,6 +113,10 @@ void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName)
updateRelativeLengthsInformation();
}
+ RenderObject* object = renderer();
+ if (!object)
+ return;
+
if (invalidateClients
|| attrName == SVGNames::markerUnitsAttr
|| attrName == SVGNames::orientAttr
@@ -120,7 +124,7 @@ void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName)
|| SVGFitToViewBox::isKnownAttribute(attrName)
|| SVGStyledElement::isKnownAttribute(attrName))
- invalidateResourceClients();
+ object->setNeedsLayout(true);
}
void SVGMarkerElement::synchronizeProperty(const QualifiedName& attrName)
@@ -166,8 +170,11 @@ void SVGMarkerElement::childrenChanged(bool changedByParser, Node* beforeChange,
{
SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!changedByParser)
- invalidateResourceClients();
+ if (changedByParser)
+ return;
+
+ if (RenderObject* object = renderer())
+ object->setNeedsLayout(true);
}
void SVGMarkerElement::setOrientToAuto()
@@ -175,7 +182,8 @@ void SVGMarkerElement::setOrientToAuto()
setOrientTypeBaseValue(SVG_MARKER_ORIENT_AUTO);
setOrientAngleBaseValue(SVGAngle());
- invalidateResourceClients();
+ if (RenderObject* object = renderer())
+ object->setNeedsLayout(true);
}
void SVGMarkerElement::setOrientToAngle(const SVGAngle& angle)
@@ -183,7 +191,8 @@ void SVGMarkerElement::setOrientToAngle(const SVGAngle& angle)
setOrientTypeBaseValue(SVG_MARKER_ORIENT_ANGLE);
setOrientAngleBaseValue(angle);
- invalidateResourceClients();
+ if (RenderObject* object = renderer())
+ object->setNeedsLayout(true);
}
RenderObject* SVGMarkerElement::createRenderer(RenderArena* arena, RenderStyle*)
diff --git a/WebCore/svg/SVGMarkerElement.h b/WebCore/svg/SVGMarkerElement.h
index 689a7e5..7b13d34 100644
--- a/WebCore/svg/SVGMarkerElement.h
+++ b/WebCore/svg/SVGMarkerElement.h
@@ -56,6 +56,8 @@ public:
SVGMarkerElement(const QualifiedName&, Document*);
virtual ~SVGMarkerElement();
+ virtual bool needsPendingResourceHandling() const { return false; }
+
AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const;
void setOrientToAuto();
diff --git a/WebCore/svg/SVGMaskElement.cpp b/WebCore/svg/SVGMaskElement.cpp
index 5013e5c..a87c28e 100644
--- a/WebCore/svg/SVGMaskElement.cpp
+++ b/WebCore/svg/SVGMaskElement.cpp
@@ -102,6 +102,10 @@ void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName)
updateRelativeLengthsInformation();
}
+ RenderObject* object = renderer();
+ if (!object)
+ return;
+
if (invalidateClients
|| attrName == SVGNames::maskUnitsAttr
|| attrName == SVGNames::maskContentUnitsAttr
@@ -109,7 +113,7 @@ void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName)
|| SVGStyledElement::isKnownAttribute(attrName))
- invalidateResourceClients();
+ object->setNeedsLayout(true);
}
void SVGMaskElement::synchronizeProperty(const QualifiedName& attrName)
@@ -141,8 +145,11 @@ void SVGMaskElement::childrenChanged(bool changedByParser, Node* beforeChange, N
{
SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!changedByParser)
- invalidateResourceClients();
+ if (changedByParser)
+ return;
+
+ if (RenderObject* object = renderer())
+ object->setNeedsLayout(true);
}
FloatRect SVGMaskElement::maskBoundingBox(const FloatRect& objectBoundingBox) const
diff --git a/WebCore/svg/SVGMaskElement.h b/WebCore/svg/SVGMaskElement.h
index e941667..2df8f31 100644
--- a/WebCore/svg/SVGMaskElement.h
+++ b/WebCore/svg/SVGMaskElement.h
@@ -40,6 +40,7 @@ namespace WebCore {
virtual ~SVGMaskElement();
virtual bool isValid() const { return SVGTests::isValid(); }
+ virtual bool needsPendingResourceHandling() const { return false; }
FloatRect maskBoundingBox(const FloatRect&) const;
virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/svg/SVGParserUtilities.cpp b/WebCore/svg/SVGParserUtilities.cpp
index 14e3d58..b5e695b 100644
--- a/WebCore/svg/SVGParserUtilities.cpp
+++ b/WebCore/svg/SVGParserUtilities.cpp
@@ -40,8 +40,8 @@ namespace WebCore {
*/
template <typename FloatType> static bool _parseNumber(const UChar*& ptr, const UChar* end, FloatType& number, bool skip)
{
- int integer, exponent;
- FloatType decimal, frac;
+ int exponent;
+ FloatType integer, decimal, frac;
int sign, expsign;
const UChar* start = ptr;
@@ -64,9 +64,19 @@ template <typename FloatType> static bool _parseNumber(const UChar*& ptr, const
// The first character of a number must be one of [0-9+-.]
return false;
- // read the integer part
+ // read the integer part, build right-to-left
+ const UChar* ptrStartIntPart = ptr;
while (ptr < end && *ptr >= '0' && *ptr <= '9')
- integer = (integer * 10) + *(ptr++) - '0';
+ ++ptr; // Advance to first non-digit.
+
+ if (ptr != ptrStartIntPart) {
+ const UChar* ptrScanIntPart = ptr - 1;
+ FloatType multiplier = 1;
+ while (ptrScanIntPart >= ptrStartIntPart) {
+ integer += multiplier * static_cast<FloatType>(*(ptrScanIntPart--) - '0');
+ multiplier *= 10;
+ }
+ }
if (ptr < end && *ptr == '.') { // read the decimals
ptr++;
diff --git a/WebCore/svg/SVGPatternElement.cpp b/WebCore/svg/SVGPatternElement.cpp
index e258946..ee42118 100644
--- a/WebCore/svg/SVGPatternElement.cpp
+++ b/WebCore/svg/SVGPatternElement.cpp
@@ -129,6 +129,10 @@ void SVGPatternElement::svgAttributeChanged(const QualifiedName& attrName)
updateRelativeLengthsInformation();
}
+ RenderObject* object = renderer();
+ if (!object)
+ return;
+
if (invalidateClients
|| attrName == SVGNames::patternUnitsAttr
|| attrName == SVGNames::patternContentUnitsAttr
@@ -139,7 +143,7 @@ void SVGPatternElement::svgAttributeChanged(const QualifiedName& attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName)
|| SVGFitToViewBox::isKnownAttribute(attrName)
|| SVGStyledElement::isKnownAttribute(attrName))
- invalidateResourceClients();
+ object->setNeedsLayout(true);
}
void SVGPatternElement::synchronizeProperty(const QualifiedName& attrName)
@@ -188,8 +192,11 @@ void SVGPatternElement::childrenChanged(bool changedByParser, Node* beforeChange
{
SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!changedByParser)
- invalidateResourceClients();
+ if (changedByParser)
+ return;
+
+ if (RenderObject* object = renderer())
+ object->setNeedsLayout(true);
}
RenderObject* SVGPatternElement::createRenderer(RenderArena* arena, RenderStyle*)
@@ -236,8 +243,10 @@ PatternAttributes SVGPatternElement::collectPatternProperties() const
current = static_cast<const SVGPatternElement*>(const_cast<const Node*>(refNode));
// Cycle detection
- if (processedPatterns.contains(current))
- return PatternAttributes();
+ if (processedPatterns.contains(current)) {
+ current = 0;
+ break;
+ }
} else
current = 0;
}
diff --git a/WebCore/svg/SVGPatternElement.h b/WebCore/svg/SVGPatternElement.h
index 105b8e2..2a8a7fe 100644
--- a/WebCore/svg/SVGPatternElement.h
+++ b/WebCore/svg/SVGPatternElement.h
@@ -47,6 +47,7 @@ namespace WebCore {
virtual ~SVGPatternElement();
virtual bool isValid() const { return SVGTests::isValid(); }
+ virtual bool needsPendingResourceHandling() const { return false; }
virtual void parseMappedAttribute(Attribute*);
virtual void svgAttributeChanged(const QualifiedName&);
diff --git a/WebCore/svg/SVGRadialGradientElement.cpp b/WebCore/svg/SVGRadialGradientElement.cpp
index 2a97b9d..a970817 100644
--- a/WebCore/svg/SVGRadialGradientElement.cpp
+++ b/WebCore/svg/SVGRadialGradientElement.cpp
@@ -83,7 +83,12 @@ void SVGRadialGradientElement::svgAttributeChanged(const QualifiedName& attrName
|| attrName == SVGNames::fyAttr
|| attrName == SVGNames::rAttr) {
updateRelativeLengthsInformation();
- invalidateResourceClients();
+
+ RenderObject* object = renderer();
+ if (!object)
+ return;
+
+ object->setNeedsLayout(true);
}
}
@@ -168,8 +173,10 @@ RadialGradientAttributes SVGRadialGradientElement::collectGradientProperties()
current = static_cast<SVGGradientElement*>(refNode);
// Cycle detection
- if (processedGradients.contains(current))
- return RadialGradientAttributes();
+ if (processedGradients.contains(current)) {
+ current = 0;
+ break;
+ }
isRadial = current->hasTagName(SVGNames::radialGradientTag);
} else
diff --git a/WebCore/svg/SVGScriptElement.cpp b/WebCore/svg/SVGScriptElement.cpp
index abe77a9..ea4ac1f 100644
--- a/WebCore/svg/SVGScriptElement.cpp
+++ b/WebCore/svg/SVGScriptElement.cpp
@@ -242,6 +242,11 @@ void SVGScriptElement::dispatchErrorEvent()
dispatchEvent(Event::create(eventNames().errorEvent, true, false));
}
+bool SVGScriptElement::shouldExecuteAsJavaScript() const
+{
+ return m_data.shouldExecuteAsJavaScript();
+}
+
}
#endif // ENABLE(SVG)
diff --git a/WebCore/svg/SVGScriptElement.h b/WebCore/svg/SVGScriptElement.h
index 770dc89..2d9cae8 100644
--- a/WebCore/svg/SVGScriptElement.h
+++ b/WebCore/svg/SVGScriptElement.h
@@ -56,7 +56,7 @@ namespace WebCore {
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
- virtual bool shouldExecuteAsJavaScript() const { return false; }
+ virtual bool shouldExecuteAsJavaScript() const;
protected:
virtual bool haveLoadedRequiredResources();
diff --git a/WebCore/svg/SVGStyleElement.cpp b/WebCore/svg/SVGStyleElement.cpp
index 48fbe69..6050e84 100644
--- a/WebCore/svg/SVGStyleElement.cpp
+++ b/WebCore/svg/SVGStyleElement.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
+ Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
Copyright (C) 2006 Apple Computer, Inc.
Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
@@ -34,12 +34,10 @@
namespace WebCore {
-using namespace SVGNames;
-
-SVGStyleElement::SVGStyleElement(const QualifiedName& tagName, Document* doc, bool createdByParser)
- : SVGElement(tagName, doc)
- , SVGLangSpace()
- , m_createdByParser(createdByParser)
+SVGStyleElement::SVGStyleElement(const QualifiedName& tagName, Document* document, bool createdByParser)
+ : SVGElement(tagName, document)
+ , SVGLangSpace()
+ , StyleElement(document, createdByParser)
{
}
@@ -90,31 +88,26 @@ void SVGStyleElement::parseMappedAttribute(Attribute* attr)
void SVGStyleElement::finishParsingChildren()
{
- StyleElement::sheet(this);
- m_createdByParser = false;
+ StyleElement::finishParsingChildren(this);
SVGElement::finishParsingChildren();
}
void SVGStyleElement::insertedIntoDocument()
{
SVGElement::insertedIntoDocument();
- document()->addStyleSheetCandidateNode(this, m_createdByParser);
- if (!m_createdByParser)
- StyleElement::insertedIntoDocument(document(), this);
+ StyleElement::insertedIntoDocument(document(), this);
}
void SVGStyleElement::removedFromDocument()
{
SVGElement::removedFromDocument();
- if (document()->renderer())
- document()->removeStyleSheetCandidateNode(this);
- StyleElement::removedFromDocument(document());
+ StyleElement::removedFromDocument(document(), this);
}
void SVGStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
+ StyleElement::childrenChanged(this);
SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- StyleElement::process(this, 0);
}
StyleSheet* SVGStyleElement::sheet()
@@ -122,13 +115,6 @@ StyleSheet* SVGStyleElement::sheet()
return StyleElement::sheet(this);
}
-bool SVGStyleElement::sheetLoaded()
-{
- document()->removePendingSheet();
- return true;
-}
-
}
-// vim:ts=4:noet
#endif // ENABLE(SVG)
diff --git a/WebCore/svg/SVGStyleElement.h b/WebCore/svg/SVGStyleElement.h
index ae7ed57..fe11f9c 100644
--- a/WebCore/svg/SVGStyleElement.h
+++ b/WebCore/svg/SVGStyleElement.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
+ Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
This library is free software; you can redistribute it and/or
@@ -20,48 +20,43 @@
#ifndef SVGStyleElement_h
#define SVGStyleElement_h
-#if ENABLE(SVG)
-#include <SVGElement.h>
+#if ENABLE(SVG)
+#include "SVGElement.h"
#include "SVGLangSpace.h"
#include "StyleElement.h"
namespace WebCore {
- class SVGStyleElement : public SVGElement,
- public SVGLangSpace,
- public StyleElement {
- public:
- SVGStyleElement(const QualifiedName&, Document*, bool createdByParser);
+class SVGStyleElement : public SVGElement
+ , public SVGLangSpace
+ , public StyleElement {
+public:
+ SVGStyleElement(const QualifiedName&, Document*, bool createdByParser);
- // Derived from: 'Element'
- virtual void parseMappedAttribute(Attribute*);
- virtual void insertedIntoDocument();
- virtual void removedFromDocument();
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void parseMappedAttribute(Attribute*);
+ virtual void insertedIntoDocument();
+ virtual void removedFromDocument();
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
- virtual void finishParsingChildren();
+ virtual void finishParsingChildren();
- virtual bool sheetLoaded();
+ virtual bool isLoading() const { return StyleElement::isLoading(); }
+ virtual bool sheetLoaded() { return StyleElement::sheetLoaded(document()); }
- virtual const AtomicString& type() const;
- void setType(const AtomicString&, ExceptionCode&);
+ virtual const AtomicString& type() const;
+ void setType(const AtomicString&, ExceptionCode&);
- virtual const AtomicString& media() const;
- void setMedia(const AtomicString&, ExceptionCode&);
+ virtual const AtomicString& media() const;
+ void setMedia(const AtomicString&, ExceptionCode&);
- virtual String title() const;
- void setTitle(const AtomicString&, ExceptionCode&);
+ virtual String title() const;
+ void setTitle(const AtomicString&, ExceptionCode&);
- StyleSheet* sheet();
-
- protected:
- bool m_createdByParser;
- };
+ StyleSheet* sheet();
+};
} // namespace WebCore
#endif // ENABLE(SVG)
#endif // SVGStyleElement_h
-
-// vim:ts=4:noet
diff --git a/WebCore/svg/SVGStyledElement.cpp b/WebCore/svg/SVGStyledElement.cpp
index 6c2993c..09447c5 100644
--- a/WebCore/svg/SVGStyledElement.cpp
+++ b/WebCore/svg/SVGStyledElement.cpp
@@ -258,17 +258,12 @@ void SVGStyledElement::synchronizeProperty(const QualifiedName& attrName)
synchronizeClassName();
}
-void SVGStyledElement::invalidateResourceClients()
+void SVGStyledElement::attach()
{
- if (document()->parsing())
- return;
-
- RenderObject* object = renderer();
- if (!object)
- return;
+ SVGElement::attach();
- if (object->isSVGResourceContainer())
- object->toRenderSVGResourceContainer()->invalidateClients();
+ if (RenderObject* object = renderer())
+ object->updateFromElement();
}
void SVGStyledElement::insertedIntoDocument()
diff --git a/WebCore/svg/SVGStyledElement.h b/WebCore/svg/SVGStyledElement.h
index 4982908..79ee0d5 100644
--- a/WebCore/svg/SVGStyledElement.h
+++ b/WebCore/svg/SVGStyledElement.h
@@ -57,6 +57,7 @@ namespace WebCore {
virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
+ virtual void attach();
virtual void insertedIntoDocument();
virtual void removedFromDocument();
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
@@ -64,8 +65,6 @@ namespace WebCore {
// Centralized place to force a manual style resolution. Hacky but needed for now.
PassRefPtr<RenderStyle> resolveStyle(RenderStyle* parentStyle);
- void invalidateResourceClients();
-
bool instanceUpdatesBlocked() const;
void setInstanceUpdatesBlocked(bool);
diff --git a/WebCore/svg/graphics/filters/SVGFETurbulence.cpp b/WebCore/svg/graphics/filters/SVGFETurbulence.cpp
index db4b0bb..8042a47 100644
--- a/WebCore/svg/graphics/filters/SVGFETurbulence.cpp
+++ b/WebCore/svg/graphics/filters/SVGFETurbulence.cpp
@@ -2,6 +2,8 @@
Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
2005 Eric Seidel <eric@webkit.org>
+ 2009 Dirk Schulze <krit@webkit.org>
+ 2010 Renata Hodovan <reni@inf.u-szeged.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -23,13 +25,31 @@
#if ENABLE(SVG) && ENABLE(FILTERS)
#include "SVGFETurbulence.h"
-#include "SVGRenderTreeAsText.h"
+
+#include "CanvasPixelArray.h"
#include "Filter.h"
+#include "ImageData.h"
+#include "SVGRenderTreeAsText.h"
+
+#include <wtf/MathExtras.h>
namespace WebCore {
-FETurbulence::FETurbulence(TurbulanceType type, const float& baseFrequencyX, const float& baseFrequencyY,
- const int& numOctaves, const float& seed, bool stitchTiles)
+/*
+ Produces results in the range [1, 2**31 - 2]. Algorithm is:
+ r = (a * r) mod m where a = randAmplitude = 16807 and
+ m = randMaximum = 2**31 - 1 = 2147483647, r = seed.
+ See [Park & Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988
+ To test: the algorithm should produce the result 1043618065
+ as the 10,000th generated number if the original seed is 1.
+*/
+static const int s_perlinNoise = 4096;
+static const long s_randMaximum = 2147483647; // 2**31 - 1
+static const int s_randAmplitude = 16807; // 7**5; primitive root of m
+static const int s_randQ = 127773; // m / a
+static const int s_randR = 2836; // m % a
+
+FETurbulence::FETurbulence(TurbulanceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles)
: FilterEffect()
, m_type(type)
, m_baseFrequencyX(baseFrequencyX)
@@ -40,8 +60,7 @@ FETurbulence::FETurbulence(TurbulanceType type, const float& baseFrequencyX, con
{
}
-PassRefPtr<FETurbulence> FETurbulence::create(TurbulanceType type, const float& baseFrequencyX, const float& baseFrequencyY,
- const int& numOctaves, const float& seed, bool stitchTiles)
+PassRefPtr<FETurbulence> FETurbulence::create(TurbulanceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles)
{
return adoptRef(new FETurbulence(type, baseFrequencyX, baseFrequencyY, numOctaves, seed, stitchTiles));
}
@@ -106,8 +125,226 @@ void FETurbulence::setStitchTiles(bool stitch)
m_stitchTiles = stitch;
}
-void FETurbulence::apply(Filter*)
+// The turbulence calculation code is an adapted version of what appears in the SVG 1.1 specification:
+// http://www.w3.org/TR/SVG11/filters.html#feTurbulence
+
+FETurbulence::PaintingData::PaintingData(long paintingSeed, const IntSize& paintingSize)
+ : seed(paintingSeed)
+ , width(0)
+ , height(0)
+ , wrapX(0)
+ , wrapY(0)
+ , channel(0)
+ , filterSize(paintingSize)
+{
+}
+
+// Compute pseudo random number.
+inline long FETurbulence::PaintingData::random()
+{
+ long result = s_randAmplitude * (seed % s_randQ) - s_randR * (seed / s_randQ);
+ if (result <= 0)
+ result += s_randMaximum;
+ seed = result;
+ return result;
+}
+
+inline float smoothCurve(float t)
+{
+ return t * t * (3 - 2 * t);
+}
+
+inline float linearInterpolation(float t, float a, float b)
+{
+ return a + t * (b - a);
+}
+
+inline void FETurbulence::initPaint(PaintingData& paintingData)
{
+ float normalizationFactor;
+
+ // The seed value clamp to the range [1, s_randMaximum - 1].
+ if (paintingData.seed <= 0)
+ paintingData.seed = -(paintingData.seed % (s_randMaximum - 1)) + 1;
+ if (paintingData.seed > s_randMaximum - 1)
+ paintingData.seed = s_randMaximum - 1;
+
+ float* gradient;
+ for (int channel = 0; channel < 4; ++channel) {
+ for (int i = 0; i < s_blockSize; ++i) {
+ paintingData.latticeSelector[i] = i;
+ gradient = paintingData.gradient[channel][i];
+ gradient[0] = static_cast<float>((paintingData.random() % (2 * s_blockSize)) - s_blockSize) / s_blockSize;
+ gradient[1] = static_cast<float>((paintingData.random() % (2 * s_blockSize)) - s_blockSize) / s_blockSize;
+ normalizationFactor = sqrtf(gradient[0] * gradient[0] + gradient[1] * gradient[1]);
+ gradient[0] /= normalizationFactor;
+ gradient[1] /= normalizationFactor;
+ }
+ }
+ for (int i = s_blockSize - 1; i >= 0; --i) {
+ int k = paintingData.latticeSelector[i];
+ int j = paintingData.random() % s_blockSize;
+ ASSERT(j >= 0);
+ ASSERT(j < 2 * s_blockSize + 2);
+ paintingData.latticeSelector[i] = paintingData.latticeSelector[j];
+ paintingData.latticeSelector[j] = k;
+ }
+ for (int i = 0; i < s_blockSize + 2; ++i) {
+ paintingData.latticeSelector[s_blockSize + i] = paintingData.latticeSelector[i];
+ for (int channel = 0; channel < 4; ++channel) {
+ paintingData.gradient[channel][s_blockSize + i][0] = paintingData.gradient[channel][i][0];
+ paintingData.gradient[channel][s_blockSize + i][1] = paintingData.gradient[channel][i][1];
+ }
+ }
+}
+
+inline void checkNoise(int& noiseValue, int limitValue, int newValue)
+{
+ if (noiseValue >= limitValue)
+ noiseValue -= newValue;
+ if (noiseValue >= limitValue - 1)
+ noiseValue -= newValue - 1;
+}
+
+float FETurbulence::noise2D(PaintingData& paintingData, const FloatPoint& noiseVector)
+{
+ struct Noise {
+ int noisePositionIntegerValue;
+ float noisePositionFractionValue;
+
+ Noise(float component)
+ {
+ float position = component + s_perlinNoise;
+ noisePositionIntegerValue = static_cast<int>(position);
+ noisePositionFractionValue = position - noisePositionIntegerValue;
+ }
+ };
+
+ Noise noiseX(noiseVector.x());
+ Noise noiseY(noiseVector.y());
+ float* q;
+ float sx, sy, a, b, u, v;
+
+ // If stitching, adjust lattice points accordingly.
+ if (m_stitchTiles) {
+ checkNoise(noiseX.noisePositionIntegerValue, paintingData.wrapX, paintingData.width);
+ checkNoise(noiseY.noisePositionIntegerValue, paintingData.wrapY, paintingData.height);
+ }
+
+ noiseX.noisePositionIntegerValue &= s_blockMask;
+ noiseY.noisePositionIntegerValue &= s_blockMask;
+ int latticeIndex = paintingData.latticeSelector[noiseX.noisePositionIntegerValue];
+ int nextLatticeIndex = paintingData.latticeSelector[(noiseX.noisePositionIntegerValue + 1) & s_blockMask];
+
+ sx = smoothCurve(noiseX.noisePositionFractionValue);
+ sy = smoothCurve(noiseY.noisePositionFractionValue);
+
+ // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
+ int temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue];
+ q = paintingData.gradient[paintingData.channel][temp];
+ u = noiseX.noisePositionFractionValue * q[0] + noiseY.noisePositionFractionValue * q[1];
+ temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue];
+ q = paintingData.gradient[paintingData.channel][temp];
+ v = (noiseX.noisePositionFractionValue - 1) * q[0] + noiseY.noisePositionFractionValue * q[1];
+ a = linearInterpolation(sx, u, v);
+ temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue + 1];
+ q = paintingData.gradient[paintingData.channel][temp];
+ u = noiseX.noisePositionFractionValue * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
+ temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue + 1];
+ q = paintingData.gradient[paintingData.channel][temp];
+ v = (noiseX.noisePositionFractionValue - 1) * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
+ b = linearInterpolation(sx, u, v);
+ return linearInterpolation(sy, a, b);
+}
+
+unsigned char FETurbulence::calculateTurbulenceValueForPoint(PaintingData& paintingData, const FloatPoint& point)
+{
+ float tileWidth = paintingData.filterSize.width();
+ ASSERT(tileWidth > 0);
+ float tileHeight = paintingData.filterSize.height();
+ ASSERT(tileHeight > 0);
+ // Adjust the base frequencies if necessary for stitching.
+ if (m_stitchTiles) {
+ // When stitching tiled turbulence, the frequencies must be adjusted
+ // so that the tile borders will be continuous.
+ if (m_baseFrequencyX) {
+ float lowFrequency = floorf(tileWidth * m_baseFrequencyX) / tileWidth;
+ float highFrequency = ceilf(tileWidth * m_baseFrequencyX) / tileWidth;
+ // BaseFrequency should be non-negative according to the standard.
+ if (m_baseFrequencyX / lowFrequency < highFrequency / m_baseFrequencyX)
+ m_baseFrequencyX = lowFrequency;
+ else
+ m_baseFrequencyX = highFrequency;
+ }
+ if (m_baseFrequencyY) {
+ float lowFrequency = floorf(tileHeight * m_baseFrequencyY) / tileHeight;
+ float highFrequency = ceilf(tileHeight * m_baseFrequencyY) / tileHeight;
+ if (m_baseFrequencyY / lowFrequency < highFrequency / m_baseFrequencyY)
+ m_baseFrequencyY = lowFrequency;
+ else
+ m_baseFrequencyY = highFrequency;
+ }
+ // Set up TurbulenceInitial stitch values.
+ paintingData.width = roundf(tileWidth * m_baseFrequencyX);
+ paintingData.wrapX = s_perlinNoise + paintingData.width;
+ paintingData.height = roundf(tileHeight * m_baseFrequencyY);
+ paintingData.wrapY = s_perlinNoise + paintingData.height;
+ }
+ float turbulenceFunctionResult = 0;
+ FloatPoint noiseVector(point.x() * m_baseFrequencyX, point.y() * m_baseFrequencyY);
+ float ratio = 1;
+ for (int octave = 0; octave < m_numOctaves; ++octave) {
+ if (m_type == FETURBULENCE_TYPE_FRACTALNOISE)
+ turbulenceFunctionResult += noise2D(paintingData, noiseVector) / ratio;
+ else
+ turbulenceFunctionResult += fabsf(noise2D(paintingData, noiseVector)) / ratio;
+ noiseVector.setX(noiseVector.x() * 2);
+ noiseVector.setY(noiseVector.y() * 2);
+ ratio *= 2;
+ if (m_stitchTiles) {
+ // Update stitch values. Subtracting s_perlinNoiseoise before the multiplication and
+ // adding it afterward simplifies to subtracting it once.
+ paintingData.width *= 2;
+ paintingData.wrapX = 2 * paintingData.wrapX - s_perlinNoise;
+ paintingData.height *= 2;
+ paintingData.wrapY = 2 * paintingData.wrapY - s_perlinNoise;
+ }
+ }
+
+ // Clamp result
+ turbulenceFunctionResult = std::max(std::min(turbulenceFunctionResult, 255.f), 0.f);
+ if (m_type == FETURBULENCE_TYPE_FRACTALNOISE)
+ return static_cast<unsigned char>(turbulenceFunctionResult * 127.5f + 127.5f); // It comes form (turbulenceFunctionResult * 255 + 255) / 2
+ return static_cast<unsigned char>(turbulenceFunctionResult * 255);
+}
+
+void FETurbulence::apply(Filter* filter)
+{
+ if (!getEffectContext())
+ return;
+
+ IntRect imageRect(IntPoint(), resultImage()->size());
+ if (!imageRect.size().width() || !imageRect.size().height())
+ return;
+
+ RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
+ PaintingData paintingData(floorf(fabsf(m_seed)), imageRect.size());
+ initPaint(paintingData);
+
+ FloatRect filterRegion = filter->filterRegion();
+ FloatPoint point;
+ point.setY(filterRegion.y());
+ int indexOfPixelChannel = 0;
+ for (int y = 0; y < imageRect.height(); ++y) {
+ point.setY(point.y() + 1);
+ point.setX(filterRegion.x());
+ for (int x = 0; x < imageRect.width(); ++x) {
+ point.setX(point.x() + 1);
+ for (paintingData.channel = 0; paintingData.channel < 4; ++paintingData.channel, ++indexOfPixelChannel)
+ imageData->data()->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(paintingData, point));
+ }
+ }
+ resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
}
void FETurbulence::dump()
diff --git a/WebCore/svg/graphics/filters/SVGFETurbulence.h b/WebCore/svg/graphics/filters/SVGFETurbulence.h
index bed0637..33e185e 100644
--- a/WebCore/svg/graphics/filters/SVGFETurbulence.h
+++ b/WebCore/svg/graphics/filters/SVGFETurbulence.h
@@ -2,6 +2,8 @@
Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
2005 Eric Seidel <eric@webkit.org>
+ 2009 Dirk Schulze <krit@webkit.org>
+ 2010 Renata Hodovan <reni@inf.u-szeged.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -28,51 +30,71 @@
namespace WebCore {
- enum TurbulanceType {
- FETURBULENCE_TYPE_UNKNOWN = 0,
- FETURBULENCE_TYPE_FRACTALNOISE = 1,
- FETURBULENCE_TYPE_TURBULENCE = 2
- };
+enum TurbulanceType {
+ FETURBULENCE_TYPE_UNKNOWN = 0,
+ FETURBULENCE_TYPE_FRACTALNOISE = 1,
+ FETURBULENCE_TYPE_TURBULENCE = 2
+};
+
+class FETurbulence : public FilterEffect {
+public:
+ static PassRefPtr<FETurbulence> create(TurbulanceType, float, float, int, float, bool);
- class FETurbulence : public FilterEffect {
- public:
- static PassRefPtr<FETurbulence> create(TurbulanceType, const float&, const float&, const int&, const float&,
- bool);
+ TurbulanceType type() const;
+ void setType(TurbulanceType);
- TurbulanceType type() const;
- void setType(TurbulanceType);
+ float baseFrequencyY() const;
+ void setBaseFrequencyY(float);
- float baseFrequencyY() const;
- void setBaseFrequencyY(float);
+ float baseFrequencyX() const;
+ void setBaseFrequencyX(float);
- float baseFrequencyX() const;
- void setBaseFrequencyX(float);
+ float seed() const;
+ void setSeed(float);
- float seed() const;
- void setSeed(float);
+ int numOctaves() const;
+ void setNumOctaves(bool);
- int numOctaves() const;
- void setNumOctaves(bool);
+ bool stitchTiles() const;
+ void setStitchTiles(bool);
- bool stitchTiles() const;
- void setStitchTiles(bool);
+ void apply(Filter*);
+ void dump();
+ TextStream& externalRepresentation(TextStream&, int indent) const;
- void apply(Filter*);
- void dump();
- TextStream& externalRepresentation(TextStream&, int indent) const;
+private:
+ static const int s_blockSize = 256;
+ static const int s_blockMask = s_blockSize - 1;
- private:
- FETurbulence(TurbulanceType, const float&, const float&, const int&, const float&,
- bool);
+ struct PaintingData {
+ long seed;
+ int latticeSelector[2 * s_blockSize + 2];
+ float gradient[4][2 * s_blockSize + 2][2];
+ int width; // How much to subtract to wrap for stitching.
+ int height;
+ int wrapX; // Minimum value to wrap.
+ int wrapY;
+ int channel;
+ IntSize filterSize;
- TurbulanceType m_type;
- float m_baseFrequencyX;
- float m_baseFrequencyY;
- int m_numOctaves;
- float m_seed;
- bool m_stitchTiles;
+ PaintingData(long paintingSeed, const IntSize& paintingSize);
+ inline long random();
};
+ FETurbulence(TurbulanceType, float, float, int, float, bool);
+
+ inline void initPaint(PaintingData&);
+ float noise2D(PaintingData&, const FloatPoint&);
+ unsigned char calculateTurbulenceValueForPoint(PaintingData&, const FloatPoint&);
+
+ TurbulanceType m_type;
+ float m_baseFrequencyX;
+ float m_baseFrequencyY;
+ int m_numOctaves;
+ float m_seed;
+ bool m_stitchTiles;
+};
+
} // namespace WebCore
#endif // ENABLE(SVG) && ENABLE(FILTERS)