summaryrefslogtreecommitdiffstats
path: root/WebCore/svg
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/svg')
-rw-r--r--WebCore/svg/SVGAllInOne.cpp3
-rw-r--r--WebCore/svg/SVGAnimateElement.cpp7
-rw-r--r--WebCore/svg/SVGAnimateMotionElement.cpp19
-rw-r--r--WebCore/svg/SVGAnimateTransformElement.cpp8
-rw-r--r--WebCore/svg/SVGCircleElement.cpp7
-rw-r--r--WebCore/svg/SVGComponentTransferFunctionElement.idl5
-rw-r--r--WebCore/svg/SVGEllipseElement.cpp7
-rw-r--r--WebCore/svg/SVGException.idl3
-rw-r--r--WebCore/svg/SVGFEBlendElement.idl7
-rw-r--r--WebCore/svg/SVGFEColorMatrixElement.idl7
-rw-r--r--WebCore/svg/SVGFECompositeElement.idl7
-rw-r--r--WebCore/svg/SVGFEConvolveMatrixElement.idl8
-rw-r--r--WebCore/svg/SVGFEDisplacementMapElement.idl7
-rw-r--r--WebCore/svg/SVGFEImageElement.cpp12
-rw-r--r--WebCore/svg/SVGFEMorphologyElement.idl7
-rw-r--r--WebCore/svg/SVGFETurbulenceElement.idl7
-rw-r--r--WebCore/svg/SVGFilterElement.cpp17
-rw-r--r--WebCore/svg/SVGFilterElement.h3
-rw-r--r--WebCore/svg/SVGFont.cpp2
-rw-r--r--WebCore/svg/SVGForeignObjectElement.cpp5
-rw-r--r--WebCore/svg/SVGGElement.cpp5
-rw-r--r--WebCore/svg/SVGGlyphElement.cpp6
-rw-r--r--WebCore/svg/SVGGradientElement.idl13
-rw-r--r--WebCore/svg/SVGImageElement.cpp5
-rw-r--r--WebCore/svg/SVGLineElement.cpp7
-rw-r--r--WebCore/svg/SVGPaint.cpp15
-rw-r--r--WebCore/svg/SVGPaint.h6
-rw-r--r--WebCore/svg/SVGParserUtilities.cpp658
-rw-r--r--WebCore/svg/SVGParserUtilities.h5
-rw-r--r--WebCore/svg/SVGPathBuilder.cpp77
-rw-r--r--WebCore/svg/SVGPathBuilder.h63
-rw-r--r--WebCore/svg/SVGPathConsumer.h68
-rw-r--r--WebCore/svg/SVGPathElement.cpp12
-rw-r--r--WebCore/svg/SVGPathParser.cpp509
-rw-r--r--WebCore/svg/SVGPathParser.h69
-rw-r--r--WebCore/svg/SVGPathSegListBuilder.cpp160
-rw-r--r--WebCore/svg/SVGPathSegListBuilder.h62
-rw-r--r--WebCore/svg/SVGPolyElement.cpp7
-rw-r--r--WebCore/svg/SVGRectElement.cpp7
-rw-r--r--WebCore/svg/SVGSVGElement.cpp11
-rw-r--r--WebCore/svg/SVGStopElement.cpp14
-rw-r--r--WebCore/svg/SVGStopElement.h1
-rw-r--r--WebCore/svg/SVGStyledElement.cpp30
-rw-r--r--WebCore/svg/SVGStyledElement.h1
-rw-r--r--WebCore/svg/SVGTRefElement.cpp3
-rw-r--r--WebCore/svg/SVGTextElement.cpp3
-rw-r--r--WebCore/svg/SVGTextPathElement.cpp3
-rw-r--r--WebCore/svg/SVGTextPositioningElement.cpp3
-rw-r--r--WebCore/svg/SVGUseElement.cpp16
-rw-r--r--WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp44
50 files changed, 1233 insertions, 798 deletions
diff --git a/WebCore/svg/SVGAllInOne.cpp b/WebCore/svg/SVGAllInOne.cpp
index c1bf281..0ad4932 100644
--- a/WebCore/svg/SVGAllInOne.cpp
+++ b/WebCore/svg/SVGAllInOne.cpp
@@ -107,7 +107,9 @@
#include "SVGNumberList.cpp"
#include "SVGPaint.cpp"
#include "SVGParserUtilities.cpp"
+#include "SVGPathBuilder.cpp"
#include "SVGPathElement.cpp"
+#include "SVGPathParser.cpp"
#include "SVGPathSegArc.cpp"
#include "SVGPathSegClosePath.cpp"
#include "SVGPathSegCurvetoCubic.cpp"
@@ -118,6 +120,7 @@
#include "SVGPathSegLinetoHorizontal.cpp"
#include "SVGPathSegLinetoVertical.cpp"
#include "SVGPathSegList.cpp"
+#include "SVGPathSegListBuilder.cpp"
#include "SVGPathSegMoveto.cpp"
#include "SVGPatternElement.cpp"
#include "SVGPointList.cpp"
diff --git a/WebCore/svg/SVGAnimateElement.cpp b/WebCore/svg/SVGAnimateElement.cpp
index ff3317b..fa4a4cf 100644
--- a/WebCore/svg/SVGAnimateElement.cpp
+++ b/WebCore/svg/SVGAnimateElement.cpp
@@ -28,6 +28,7 @@
#include "SVGColor.h"
#include "SVGParserUtilities.h"
#include "SVGPathSegList.h"
+#include "SVGPathSegListBuilder.h"
#include "SVGPointList.h"
#include <math.h>
@@ -189,9 +190,11 @@ bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const
}
} else if (m_propertyType == PathProperty) {
m_fromPath = SVGPathSegList::create(SVGNames::dAttr);
- if (pathSegListFromSVGData(m_fromPath.get(), fromString)) {
+ SVGPathSegListBuilder fromParser(m_fromPath.get());
+ if (fromParser.build(fromString, UnalteredParsing)) {
m_toPath = SVGPathSegList::create(SVGNames::dAttr);
- if (pathSegListFromSVGData(m_toPath.get(), toString))
+ SVGPathSegListBuilder toParser(m_toPath.get());
+ if (toParser.build(toString, UnalteredParsing))
return true;
}
m_fromPath.clear();
diff --git a/WebCore/svg/SVGAnimateMotionElement.cpp b/WebCore/svg/SVGAnimateMotionElement.cpp
index 9a0da7f..a3f4ef9 100644
--- a/WebCore/svg/SVGAnimateMotionElement.cpp
+++ b/WebCore/svg/SVGAnimateMotionElement.cpp
@@ -28,9 +28,11 @@
#include "Attribute.h"
#include "RenderObject.h"
+#include "RenderSVGResource.h"
#include "SVGElementInstance.h"
#include "SVGMPathElement.h"
#include "SVGParserUtilities.h"
+#include "SVGPathBuilder.h"
#include "SVGPathElement.h"
#include "SVGTransformList.h"
#include <math.h>
@@ -87,7 +89,9 @@ void SVGAnimateMotionElement::parseMappedAttribute(Attribute* attr)
{
if (attr->name() == SVGNames::pathAttr) {
m_path = Path();
- pathFromSVGData(m_path, attr->value());
+ SVGPathBuilder builder(m_path);
+ // FIXME: We should analyse the returned value.
+ builder.build(attr->value());
} else
SVGAnimationElement::parseMappedAttribute(attr);
}
@@ -214,9 +218,12 @@ void SVGAnimateMotionElement::applyResultsToTarget()
{
// We accumulate to the target element transform list so there is not much to do here.
SVGElement* targetElement = this->targetElement();
- if (targetElement && targetElement->renderer())
- targetElement->renderer()->setNeedsLayout(true);
-
+ if (!targetElement)
+ return;
+
+ if (RenderObject* renderer = targetElement->renderer())
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+
// ...except in case where we have additional instances in <use> trees.
const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
@@ -228,7 +235,7 @@ void SVGAnimateMotionElement::applyResultsToTarget()
transform->setMatrix(t->a(), t->b(), t->c(), t->d(), t->e(), t->f());
if (RenderObject* renderer = shadowTreeElement->renderer()) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
}
}
@@ -248,5 +255,3 @@ float SVGAnimateMotionElement::calculateDistance(const String& fromString, const
}
#endif // ENABLE(SVG)
-
-// vim:ts=4:noet
diff --git a/WebCore/svg/SVGAnimateTransformElement.cpp b/WebCore/svg/SVGAnimateTransformElement.cpp
index 1a305bb..6ca9447 100644
--- a/WebCore/svg/SVGAnimateTransformElement.cpp
+++ b/WebCore/svg/SVGAnimateTransformElement.cpp
@@ -30,6 +30,7 @@
#include "AffineTransform.h"
#include "Attribute.h"
#include "RenderObject.h"
+#include "RenderSVGResource.h"
#include "SVGAngle.h"
#include "SVGElementInstance.h"
#include "SVGGradientElement.h"
@@ -172,9 +173,12 @@ void SVGAnimateTransformElement::applyResultsToTarget()
return;
// We accumulate to the target element transform list so there is not much to do here.
SVGElement* targetElement = this->targetElement();
+ if (!targetElement)
+ return;
+
if (RenderObject* renderer = targetElement->renderer()) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
// ...except in case where we have additional instances in <use> trees.
@@ -192,7 +196,7 @@ void SVGAnimateTransformElement::applyResultsToTarget()
static_cast<SVGGradientElement*>(shadowTreeElement)->setGradientTransformBaseValue(transformList.get());
if (RenderObject* renderer = shadowTreeElement->renderer()) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
}
}
diff --git a/WebCore/svg/SVGCircleElement.cpp b/WebCore/svg/SVGCircleElement.cpp
index c90b8e3..f8c9ccd 100644
--- a/WebCore/svg/SVGCircleElement.cpp
+++ b/WebCore/svg/SVGCircleElement.cpp
@@ -26,6 +26,7 @@
#include "Attribute.h"
#include "FloatPoint.h"
#include "RenderPath.h"
+#include "RenderSVGResource.h"
#include "SVGLength.h"
#include "SVGNames.h"
@@ -84,20 +85,20 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName)
if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (isLengthAttribute) {
renderer->setNeedsPathUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (SVGTests::isKnownAttribute(attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
void SVGCircleElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGComponentTransferFunctionElement.idl b/WebCore/svg/SVGComponentTransferFunctionElement.idl
index 950f77d..0a9e05d 100644
--- a/WebCore/svg/SVGComponentTransferFunctionElement.idl
+++ b/WebCore/svg/SVGComponentTransferFunctionElement.idl
@@ -25,7 +25,10 @@
module svg {
- interface [Conditional=SVG&FILTERS] SVGComponentTransferFunctionElement : SVGElement {
+ interface [
+ Conditional=SVG&FILTERS,
+ DontCheckEnums
+ ] SVGComponentTransferFunctionElement : SVGElement {
// Component Transfer Types
const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0;
const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1;
diff --git a/WebCore/svg/SVGEllipseElement.cpp b/WebCore/svg/SVGEllipseElement.cpp
index 5509c2d..963b4b0 100644
--- a/WebCore/svg/SVGEllipseElement.cpp
+++ b/WebCore/svg/SVGEllipseElement.cpp
@@ -26,6 +26,7 @@
#include "Attribute.h"
#include "FloatPoint.h"
#include "RenderPath.h"
+#include "RenderSVGResource.h"
#include "SVGLength.h"
#include "SVGNames.h"
@@ -90,20 +91,20 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName)
if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (isLengthAttribute) {
renderer->setNeedsPathUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (SVGTests::isKnownAttribute(attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
void SVGEllipseElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGException.idl b/WebCore/svg/SVGException.idl
index db565ff..3f1f8ec 100644
--- a/WebCore/svg/SVGException.idl
+++ b/WebCore/svg/SVGException.idl
@@ -21,7 +21,8 @@
module svg {
interface [
- Conditional=SVG
+ Conditional=SVG,
+ DontCheckEnums
] SVGException {
readonly attribute unsigned short code;
diff --git a/WebCore/svg/SVGFEBlendElement.idl b/WebCore/svg/SVGFEBlendElement.idl
index bb6d86d..0c08603 100644
--- a/WebCore/svg/SVGFEBlendElement.idl
+++ b/WebCore/svg/SVGFEBlendElement.idl
@@ -25,8 +25,11 @@
module svg {
- interface [Conditional=SVG&FILTERS] SVGFEBlendElement : SVGElement,
- SVGFilterPrimitiveStandardAttributes {
+ interface [
+ Conditional=SVG&FILTERS,
+ DontCheckEnums
+ ] SVGFEBlendElement : SVGElement,
+ SVGFilterPrimitiveStandardAttributes {
// Blend Mode Types
const unsigned short SVG_FEBLEND_MODE_UNKNOWN = 0;
const unsigned short SVG_FEBLEND_MODE_NORMAL = 1;
diff --git a/WebCore/svg/SVGFEColorMatrixElement.idl b/WebCore/svg/SVGFEColorMatrixElement.idl
index d704906..61c5b4a 100644
--- a/WebCore/svg/SVGFEColorMatrixElement.idl
+++ b/WebCore/svg/SVGFEColorMatrixElement.idl
@@ -25,8 +25,11 @@
module svg {
- interface [Conditional=SVG&FILTERS] SVGFEColorMatrixElement : SVGElement,
- SVGFilterPrimitiveStandardAttributes {
+ interface [
+ Conditional=SVG&FILTERS,
+ DontCheckEnums
+ ] SVGFEColorMatrixElement : SVGElement,
+ SVGFilterPrimitiveStandardAttributes {
// Color Matrix Types
const unsigned short SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0;
const unsigned short SVG_FECOLORMATRIX_TYPE_MATRIX = 1;
diff --git a/WebCore/svg/SVGFECompositeElement.idl b/WebCore/svg/SVGFECompositeElement.idl
index d3adb25..af1d5cf 100644
--- a/WebCore/svg/SVGFECompositeElement.idl
+++ b/WebCore/svg/SVGFECompositeElement.idl
@@ -25,8 +25,11 @@
module svg {
- interface [Conditional=SVG&FILTERS] SVGFECompositeElement : SVGElement,
- SVGFilterPrimitiveStandardAttributes {
+ interface [
+ Conditional=SVG&FILTERS,
+ DontCheckEnums
+ ] SVGFECompositeElement : SVGElement,
+ SVGFilterPrimitiveStandardAttributes {
// Composite Operators
const unsigned short SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0;
const unsigned short SVG_FECOMPOSITE_OPERATOR_OVER = 1;
diff --git a/WebCore/svg/SVGFEConvolveMatrixElement.idl b/WebCore/svg/SVGFEConvolveMatrixElement.idl
index 5be4c33..afe859d 100644
--- a/WebCore/svg/SVGFEConvolveMatrixElement.idl
+++ b/WebCore/svg/SVGFEConvolveMatrixElement.idl
@@ -25,8 +25,12 @@
module svg {
- interface [Conditional=SVG&FILTERS, GenerateConstructor] SVGFEConvolveMatrixElement : SVGElement,
- SVGFilterPrimitiveStandardAttributes {
+ interface [
+ Conditional=SVG&FILTERS,
+ GenerateConstructor,
+ DontCheckEnums
+ ] SVGFEConvolveMatrixElement : SVGElement,
+ SVGFilterPrimitiveStandardAttributes {
// Edge Mode Values
const unsigned short SVG_EDGEMODE_UNKNOWN = 0;
const unsigned short SVG_EDGEMODE_DUPLICATE = 1;
diff --git a/WebCore/svg/SVGFEDisplacementMapElement.idl b/WebCore/svg/SVGFEDisplacementMapElement.idl
index b003e8f..1eb9440 100644
--- a/WebCore/svg/SVGFEDisplacementMapElement.idl
+++ b/WebCore/svg/SVGFEDisplacementMapElement.idl
@@ -25,8 +25,11 @@
module svg {
- interface [Conditional=SVG&FILTERS] SVGFEDisplacementMapElement : SVGElement,
- SVGFilterPrimitiveStandardAttributes {
+ interface [
+ Conditional=SVG&FILTERS,
+ DontCheckEnums
+ ] SVGFEDisplacementMapElement : SVGElement,
+ SVGFilterPrimitiveStandardAttributes {
// Channel Selectors
const unsigned short SVG_CHANNEL_UNKNOWN = 0;
const unsigned short SVG_CHANNEL_R = 1;
diff --git a/WebCore/svg/SVGFEImageElement.cpp b/WebCore/svg/SVGFEImageElement.cpp
index 84f8734..1f7164f 100644
--- a/WebCore/svg/SVGFEImageElement.cpp
+++ b/WebCore/svg/SVGFEImageElement.cpp
@@ -29,6 +29,7 @@
#include "DocLoader.h"
#include "Document.h"
#include "RenderObject.h"
+#include "RenderSVGResource.h"
#include "SVGLength.h"
#include "SVGNames.h"
#include "SVGPreserveAspectRatio.h"
@@ -107,7 +108,16 @@ void SVGFEImageElement::synchronizeProperty(const QualifiedName& attrName)
void SVGFEImageElement::notifyFinished(CachedResource*)
{
- SVGStyledElement::invalidateResourcesInAncestorChain();
+ if (!inDocument())
+ return;
+
+ Element* parent = parentElement();
+ ASSERT(parent);
+
+ if (!parent->hasTagName(SVGNames::filterTag) || !parent->renderer())
+ return;
+
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(parent->renderer());
}
PassRefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*)
diff --git a/WebCore/svg/SVGFEMorphologyElement.idl b/WebCore/svg/SVGFEMorphologyElement.idl
index ffd2289..64023e8 100644
--- a/WebCore/svg/SVGFEMorphologyElement.idl
+++ b/WebCore/svg/SVGFEMorphologyElement.idl
@@ -25,8 +25,11 @@
module svg {
- interface [Conditional=SVG&FILTERS] SVGFEMorphologyElement : SVGElement,
- SVGFilterPrimitiveStandardAttributes {
+ interface [
+ Conditional=SVG&FILTERS,
+ DontCheckEnums
+ ] SVGFEMorphologyElement : SVGElement,
+ SVGFilterPrimitiveStandardAttributes {
// Morphology Operators
const unsigned short SVG_MORPHOLOGY_OPERATOR_UNKNOWN = 0;
const unsigned short SVG_MORPHOLOGY_OPERATOR_ERODE = 1;
diff --git a/WebCore/svg/SVGFETurbulenceElement.idl b/WebCore/svg/SVGFETurbulenceElement.idl
index 934eddf..f011d99 100644
--- a/WebCore/svg/SVGFETurbulenceElement.idl
+++ b/WebCore/svg/SVGFETurbulenceElement.idl
@@ -25,8 +25,11 @@
module svg {
- interface [Conditional=SVG&FILTERS] SVGFETurbulenceElement : SVGElement,
- SVGFilterPrimitiveStandardAttributes {
+ interface [
+ Conditional=SVG&FILTERS,
+ DontCheckEnums
+ ] SVGFETurbulenceElement : SVGElement,
+ SVGFilterPrimitiveStandardAttributes {
// Turbulence Types
const unsigned short SVG_TURBULENCE_TYPE_UNKNOWN = 0;
const unsigned short SVG_TURBULENCE_TYPE_FRACTALNOISE = 1;
diff --git a/WebCore/svg/SVGFilterElement.cpp b/WebCore/svg/SVGFilterElement.cpp
index b86b8c4..4387e71 100644
--- a/WebCore/svg/SVGFilterElement.cpp
+++ b/WebCore/svg/SVGFilterElement.cpp
@@ -62,8 +62,11 @@ SVGFilterElement::~SVGFilterElement()
{
}
-void SVGFilterElement::setFilterRes(unsigned long, unsigned long) const
+void SVGFilterElement::setFilterRes(unsigned long filterResX, unsigned long filterResY)
{
+ setFilterResXBaseValue(filterResX);
+ setFilterResYBaseValue(filterResY);
+ invalidateResourceClients();
}
void SVGFilterElement::parseMappedAttribute(Attribute* attr)
@@ -122,10 +125,10 @@ void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName)
|| attrName == SVGNames::filterUnitsAttr
|| attrName == SVGNames::primitiveUnitsAttr
|| attrName == SVGNames::filterResAttr
+ || SVGStyledElement::isKnownAttribute(attrName)
|| SVGURIReference::isKnownAttribute(attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
- || SVGExternalResourcesRequired::isKnownAttribute(attrName)
- || SVGStyledElement::isKnownAttribute(attrName))
+ || SVGExternalResourcesRequired::isKnownAttribute(attrName))
invalidateResourceClients();
}
@@ -168,6 +171,14 @@ void SVGFilterElement::synchronizeProperty(const QualifiedName& attrName)
synchronizeHref();
}
+void SVGFilterElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+
+ if (!changedByParser)
+ invalidateResourceClients();
+}
+
FloatRect SVGFilterElement::filterBoundingBox(const FloatRect& objectBoundingBox) const
{
FloatRect filterBBox;
diff --git a/WebCore/svg/SVGFilterElement.h b/WebCore/svg/SVGFilterElement.h
index 85679c7..7b0192c 100644
--- a/WebCore/svg/SVGFilterElement.h
+++ b/WebCore/svg/SVGFilterElement.h
@@ -43,12 +43,13 @@ public:
SVGFilterElement(const QualifiedName&, Document*);
virtual ~SVGFilterElement();
- void setFilterRes(unsigned long filterResX, unsigned long filterResY) const;
+ void setFilterRes(unsigned long filterResX, unsigned long filterResY);
FloatRect filterBoundingBox(const FloatRect&) const;
virtual void parseMappedAttribute(Attribute*);
virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
diff --git a/WebCore/svg/SVGFont.cpp b/WebCore/svg/SVGFont.cpp
index 5436688..6abea60 100644
--- a/WebCore/svg/SVGFont.cpp
+++ b/WebCore/svg/SVGFont.cpp
@@ -413,7 +413,7 @@ static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun&
}
SVGTextRunWalker<SVGTextRunWalkerMeasuredLengthData> runWalker(fontData, fontElement, data, floatWidthUsingSVGFontCallback, floatWidthMissingGlyphCallback);
- runWalker.walk(run, isVerticalText, language, 0, run.length());
+ runWalker.walk(run, isVerticalText, language, from, to);
charsConsumed = data.charsConsumed;
glyphName = data.glyphName;
return data.length;
diff --git a/WebCore/svg/SVGForeignObjectElement.cpp b/WebCore/svg/SVGForeignObjectElement.cpp
index d6bf1cf..7ffe1c6 100644
--- a/WebCore/svg/SVGForeignObjectElement.cpp
+++ b/WebCore/svg/SVGForeignObjectElement.cpp
@@ -28,6 +28,7 @@
#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "RenderForeignObject.h"
+#include "RenderSVGResource.h"
#include "SVGLength.h"
#include "SVGNames.h"
#include <wtf/Assertions.h>
@@ -90,7 +91,7 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
@@ -98,7 +99,7 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
|| SVGTests::isKnownAttribute(attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
void SVGForeignObjectElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGGElement.cpp b/WebCore/svg/SVGGElement.cpp
index eceac41..a830096 100644
--- a/WebCore/svg/SVGGElement.cpp
+++ b/WebCore/svg/SVGGElement.cpp
@@ -24,6 +24,7 @@
#include "SVGGElement.h"
#include "RenderSVGHiddenContainer.h"
+#include "RenderSVGResource.h"
#include "RenderSVGTransformableContainer.h"
namespace WebCore {
@@ -62,14 +63,14 @@ void SVGGElement::svgAttributeChanged(const QualifiedName& attrName)
if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (SVGTests::isKnownAttribute(attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
void SVGGElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGGlyphElement.cpp b/WebCore/svg/SVGGlyphElement.cpp
index d5b7531..054db11 100644
--- a/WebCore/svg/SVGGlyphElement.cpp
+++ b/WebCore/svg/SVGGlyphElement.cpp
@@ -29,7 +29,7 @@
#include "SVGFontElement.h"
#include "SVGFontFaceElement.h"
#include "SVGNames.h"
-#include "SVGParserUtilities.h"
+#include "SVGPathBuilder.h"
#include "SimpleFontData.h"
#include "XMLNames.h"
@@ -102,7 +102,9 @@ static inline SVGGlyphIdentifier::Orientation parseOrientation(const AtomicStrin
static inline Path parsePathData(const AtomicString& value)
{
Path result;
- pathFromSVGData(result, value);
+ SVGPathBuilder builder(result);
+ // FIXME: We should analyse the returned value.
+ builder.build(value);
return result;
}
diff --git a/WebCore/svg/SVGGradientElement.idl b/WebCore/svg/SVGGradientElement.idl
index 7485780..16ac636 100644
--- a/WebCore/svg/SVGGradientElement.idl
+++ b/WebCore/svg/SVGGradientElement.idl
@@ -25,11 +25,14 @@
module svg {
- interface [Conditional=SVG] SVGGradientElement : SVGElement,
- SVGURIReference,
- SVGExternalResourcesRequired,
- SVGStylable
- /* SVGUnitTypes */ {
+ interface [
+ Conditional=SVG,
+ DontCheckEnums
+ ] SVGGradientElement : SVGElement,
+ SVGURIReference,
+ SVGExternalResourcesRequired,
+ SVGStylable
+ /* SVGUnitTypes */ {
// Spread Method Types
const unsigned short SVG_SPREADMETHOD_UNKNOWN = 0;
const unsigned short SVG_SPREADMETHOD_PAD = 1;
diff --git a/WebCore/svg/SVGImageElement.cpp b/WebCore/svg/SVGImageElement.cpp
index 711e9f3..75f05cf 100644
--- a/WebCore/svg/SVGImageElement.cpp
+++ b/WebCore/svg/SVGImageElement.cpp
@@ -27,6 +27,7 @@
#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "RenderSVGImage.h"
+#include "RenderSVGResource.h"
#include "SVGDocument.h"
#include "SVGLength.h"
#include "SVGPreserveAspectRatio.h"
@@ -105,7 +106,7 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
@@ -114,7 +115,7 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
|| SVGTests::isKnownAttribute(attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
void SVGImageElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGLineElement.cpp b/WebCore/svg/SVGLineElement.cpp
index c6e5e04..0898319 100644
--- a/WebCore/svg/SVGLineElement.cpp
+++ b/WebCore/svg/SVGLineElement.cpp
@@ -26,6 +26,7 @@
#include "Attribute.h"
#include "FloatPoint.h"
#include "RenderPath.h"
+#include "RenderSVGResource.h"
#include "SVGLength.h"
#include "SVGNames.h"
@@ -86,20 +87,20 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName)
if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (isLengthAttribute) {
renderer->setNeedsPathUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (SVGTests::isKnownAttribute(attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
void SVGLineElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGPaint.cpp b/WebCore/svg/SVGPaint.cpp
index 82a5fe4..6d60979 100644
--- a/WebCore/svg/SVGPaint.cpp
+++ b/WebCore/svg/SVGPaint.cpp
@@ -1,6 +1,7 @@
/*
- 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) Research In Motion Limited 2010. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -19,8 +20,10 @@
*/
#include "config.h"
+
#if ENABLE(SVG)
#include "SVGPaint.h"
+#include "SVGURIReference.h"
namespace WebCore {
@@ -108,8 +111,14 @@ String SVGPaint::cssText() const
return SVGColor::cssText();
}
+bool SVGPaint::matchesTargetURI(const String& referenceId)
+{
+ if (m_paintType != SVG_PAINTTYPE_URI && m_paintType != SVG_PAINTTYPE_URI_RGBCOLOR)
+ return false;
+
+ return referenceId == SVGURIReference::getTarget(m_uri);
+}
+
}
-// vim:ts=4:noet
#endif // ENABLE(SVG)
-
diff --git a/WebCore/svg/SVGPaint.h b/WebCore/svg/SVGPaint.h
index 032f715..aa696d1 100644
--- a/WebCore/svg/SVGPaint.h
+++ b/WebCore/svg/SVGPaint.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>
Copyright (C) 2006 Samuel Weinig (sam.weinig@gmial.com)
@@ -78,6 +78,8 @@ namespace WebCore {
static SVGPaint* defaultFill();
static SVGPaint* defaultStroke();
+ bool matchesTargetURI(const String& referenceId);
+
private:
SVGPaint();
SVGPaint(const String& uri);
@@ -96,5 +98,3 @@ namespace WebCore {
#endif // ENABLE(SVG)
#endif // SVGPaint_h
-
-// vim:ts=4:noet
diff --git a/WebCore/svg/SVGParserUtilities.cpp b/WebCore/svg/SVGParserUtilities.cpp
index c722232..14e3d58 100644
--- a/WebCore/svg/SVGParserUtilities.cpp
+++ b/WebCore/svg/SVGParserUtilities.cpp
@@ -21,31 +21,16 @@
*/
#include "config.h"
+
#if ENABLE(SVG)
#include "SVGParserUtilities.h"
+#include "Document.h"
#include "ExceptionCode.h"
-#include "FloatConversion.h"
#include "FloatPoint.h"
-#include "Path.h"
#include "PlatformString.h"
-#include "SVGPathSegList.h"
-#include "SVGPathSegArc.h"
-#include "SVGPathSegClosePath.h"
-#include "SVGPathSegCurvetoCubic.h"
-#include "SVGPathSegCurvetoCubicSmooth.h"
-#include "SVGPathSegCurvetoQuadratic.h"
-#include "SVGPathSegCurvetoQuadraticSmooth.h"
-#include "SVGPathSegLineto.h"
-#include "SVGPathSegLinetoHorizontal.h"
-#include "SVGPathSegLinetoVertical.h"
-#include "SVGPathSegList.h"
-#include "SVGPathSegMoveto.h"
#include "SVGPointList.h"
-#include "SVGPathElement.h"
-#include <math.h>
#include <wtf/ASCIICType.h>
-#include <wtf/MathExtras.h>
namespace WebCore {
@@ -135,15 +120,9 @@ bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip)
return _parseNumber(ptr, end, number, skip);
}
-// Only used for parsing Paths
-static bool parseNumber(const UChar*& ptr, const UChar* end, double& number, bool skip = true)
-{
- return _parseNumber(ptr, end, number, skip);
-}
-
// only used to parse largeArcFlag and sweepFlag which must be a "0" or "1"
// and might not have any whitespace/comma after it
-static bool parseArcFlag(const UChar*& ptr, const UChar* end, bool& flag)
+bool parseArcFlag(const UChar*& ptr, const UChar* end, bool& flag)
{
const UChar flagChar = *ptr++;
if (flagChar == '0')
@@ -210,637 +189,6 @@ bool pointsListFromSVGData(SVGPointList* pointsList, const String& points)
return cur == end && !delimParsed;
}
- /**
- * Parser for svg path data, contained in the d attribute.
- *
- * The parser delivers encountered commands and parameters by calling
- * methods that correspond to those commands. Clients have to derive
- * from this class and implement the abstract command methods.
- *
- * There are two operating modes. By default the parser just delivers unaltered
- * svg path data commands and parameters. In the second mode, it will convert all
- * relative coordinates to absolute ones, and convert all curves to cubic beziers.
- */
- class SVGPathParser {
- public:
- virtual ~SVGPathParser() { }
- bool parseSVG(const String& d, bool process = false);
-
- protected:
- virtual void svgMoveTo(double x1, double y1, bool closed, bool abs = true) = 0;
- virtual void svgLineTo(double x1, double y1, bool abs = true) = 0;
- virtual void svgLineToHorizontal(double, bool /*abs*/ = true) { }
- virtual void svgLineToVertical(double /*y*/, bool /*abs*/ = true) { }
- virtual void svgCurveToCubic(double x1, double y1, double x2, double y2, double x, double y, bool abs = true) = 0;
- virtual void svgCurveToCubicSmooth(double /*x*/, double /*y*/, double /*x2*/, double /*y2*/, bool /*abs*/ = true) { }
- virtual void svgCurveToQuadratic(double /*x*/, double /*y*/, double /*x1*/, double /*y1*/, bool /*abs*/ = true) { }
- virtual void svgCurveToQuadraticSmooth(double /*x*/, double /*y*/, bool /*abs*/ = true) { }
- virtual void svgArcTo(double /*x*/, double /*y*/, double /*r1*/, double /*r2*/, double /*angle*/, bool /*largeArcFlag*/, bool /*sweepFlag*/, bool /*abs*/ = true) { }
- virtual void svgClosePath() = 0;
-
- private:
- void calculateArc(bool relative, double& curx, double& cury, double angle, double x, double y, double r1, double r2, bool largeArcFlag, bool sweepFlag);
- };
-
-bool SVGPathParser::parseSVG(const String& s, bool process)
-{
- const UChar* ptr = s.characters();
- const UChar* end = ptr + s.length();
-
- double contrlx, contrly, curx, cury, subpathx, subpathy, tox, toy, x1, y1, x2, y2, xc, yc;
- double px1, py1, px2, py2, px3, py3;
- bool closed = true;
-
- if (!skipOptionalSpaces(ptr, end)) // skip any leading spaces
- return false;
-
- char command = *(ptr++), lastCommand = ' ';
- if (command != 'm' && command != 'M') // path must start with moveto
- return false;
-
- subpathx = subpathy = curx = cury = contrlx = contrly = 0.0;
- while (1) {
- skipOptionalSpaces(ptr, end); // skip spaces between command and first coord
-
- bool relative = false;
-
- switch (command)
- {
- case 'm':
- relative = true;
- case 'M':
- {
- if (!parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy))
- return false;
-
- if (process) {
- subpathx = curx = relative ? curx + tox : tox;
- subpathy = cury = relative ? cury + toy : toy;
-
- svgMoveTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury), closed);
- } else
- svgMoveTo(narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), closed, !relative);
- closed = false;
- break;
- }
- case 'l':
- relative = true;
- case 'L':
- {
- if (!parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy))
- return false;
-
- if (process) {
- curx = relative ? curx + tox : tox;
- cury = relative ? cury + toy : toy;
-
- svgLineTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury));
- }
- else
- svgLineTo(narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), !relative);
- break;
- }
- case 'h':
- {
- if (!parseNumber(ptr, end, tox))
- return false;
- if (process) {
- curx = curx + tox;
- svgLineTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury));
- }
- else
- svgLineToHorizontal(narrowPrecisionToFloat(tox), false);
- break;
- }
- case 'H':
- {
- if (!parseNumber(ptr, end, tox))
- return false;
- if (process) {
- curx = tox;
- svgLineTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury));
- }
- else
- svgLineToHorizontal(narrowPrecisionToFloat(tox));
- break;
- }
- case 'v':
- {
- if (!parseNumber(ptr, end, toy))
- return false;
- if (process) {
- cury = cury + toy;
- svgLineTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury));
- }
- else
- svgLineToVertical(narrowPrecisionToFloat(toy), false);
- break;
- }
- case 'V':
- {
- if (!parseNumber(ptr, end, toy))
- return false;
- if (process) {
- cury = toy;
- svgLineTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury));
- }
- else
- svgLineToVertical(narrowPrecisionToFloat(toy));
- break;
- }
- case 'z':
- case 'Z':
- {
- // reset curx, cury for next path
- if (process) {
- curx = subpathx;
- cury = subpathy;
- }
- closed = true;
- svgClosePath();
- break;
- }
- case 'c':
- relative = true;
- case 'C':
- {
- if (!parseNumber(ptr, end, x1) || !parseNumber(ptr, end, y1) ||
- !parseNumber(ptr, end, x2) || !parseNumber(ptr, end, y2) ||
- !parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy))
- return false;
-
- if (process) {
- px1 = relative ? curx + x1 : x1;
- py1 = relative ? cury + y1 : y1;
- px2 = relative ? curx + x2 : x2;
- py2 = relative ? cury + y2 : y2;
- px3 = relative ? curx + tox : tox;
- py3 = relative ? cury + toy : toy;
-
- svgCurveToCubic(narrowPrecisionToFloat(px1), narrowPrecisionToFloat(py1), narrowPrecisionToFloat(px2),
- narrowPrecisionToFloat(py2), narrowPrecisionToFloat(px3), narrowPrecisionToFloat(py3));
-
- contrlx = relative ? curx + x2 : x2;
- contrly = relative ? cury + y2 : y2;
- curx = relative ? curx + tox : tox;
- cury = relative ? cury + toy : toy;
- }
- else
- svgCurveToCubic(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1), narrowPrecisionToFloat(x2),
- narrowPrecisionToFloat(y2), narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), !relative);
-
- break;
- }
- case 's':
- relative = true;
- case 'S':
- {
- if (!parseNumber(ptr, end, x2) || !parseNumber(ptr, end, y2) ||
- !parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy))
- return false;
-
- if (!(lastCommand == 'c' || lastCommand == 'C' ||
- lastCommand == 's' || lastCommand == 'S')) {
- contrlx = curx;
- contrly = cury;
- }
-
- if (process) {
- px1 = 2 * curx - contrlx;
- py1 = 2 * cury - contrly;
- px2 = relative ? curx + x2 : x2;
- py2 = relative ? cury + y2 : y2;
- px3 = relative ? curx + tox : tox;
- py3 = relative ? cury + toy : toy;
-
- svgCurveToCubic(narrowPrecisionToFloat(px1), narrowPrecisionToFloat(py1), narrowPrecisionToFloat(px2),
- narrowPrecisionToFloat(py2), narrowPrecisionToFloat(px3), narrowPrecisionToFloat(py3));
-
- contrlx = relative ? curx + x2 : x2;
- contrly = relative ? cury + y2 : y2;
- curx = relative ? curx + tox : tox;
- cury = relative ? cury + toy : toy;
- }
- else
- svgCurveToCubicSmooth(narrowPrecisionToFloat(x2), narrowPrecisionToFloat(y2),
- narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), !relative);
- break;
- }
- case 'q':
- relative = true;
- case 'Q':
- {
- if (!parseNumber(ptr, end, x1) || !parseNumber(ptr, end, y1) ||
- !parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy))
- return false;
-
- if (process) {
- px1 = relative ? (curx + 2 * (x1 + curx)) * (1.0 / 3.0) : (curx + 2 * x1) * (1.0 / 3.0);
- py1 = relative ? (cury + 2 * (y1 + cury)) * (1.0 / 3.0) : (cury + 2 * y1) * (1.0 / 3.0);
- px2 = relative ? ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0) : (tox + 2 * x1) * (1.0 / 3.0);
- py2 = relative ? ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0) : (toy + 2 * y1) * (1.0 / 3.0);
- px3 = relative ? curx + tox : tox;
- py3 = relative ? cury + toy : toy;
-
- svgCurveToCubic(narrowPrecisionToFloat(px1), narrowPrecisionToFloat(py1), narrowPrecisionToFloat(px2),
- narrowPrecisionToFloat(py2), narrowPrecisionToFloat(px3), narrowPrecisionToFloat(py3));
-
- contrlx = relative ? curx + x1 : x1;
- contrly = relative ? cury + y1 : y1;
- curx = relative ? curx + tox : tox;
- cury = relative ? cury + toy : toy;
- }
- else
- svgCurveToQuadratic(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1),
- narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), !relative);
- break;
- }
- case 't':
- relative = true;
- case 'T':
- {
- if (!parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy))
- return false;
- if (!(lastCommand == 'q' || lastCommand == 'Q' ||
- lastCommand == 't' || lastCommand == 'T')) {
- contrlx = curx;
- contrly = cury;
- }
-
- if (process) {
- xc = 2 * curx - contrlx;
- yc = 2 * cury - contrly;
-
- px1 = relative ? (curx + 2 * xc) * (1.0 / 3.0) : (curx + 2 * xc) * (1.0 / 3.0);
- py1 = relative ? (cury + 2 * yc) * (1.0 / 3.0) : (cury + 2 * yc) * (1.0 / 3.0);
- px2 = relative ? ((curx + tox) + 2 * xc) * (1.0 / 3.0) : (tox + 2 * xc) * (1.0 / 3.0);
- py2 = relative ? ((cury + toy) + 2 * yc) * (1.0 / 3.0) : (toy + 2 * yc) * (1.0 / 3.0);
- px3 = relative ? curx + tox : tox;
- py3 = relative ? cury + toy : toy;
-
- svgCurveToCubic(narrowPrecisionToFloat(px1), narrowPrecisionToFloat(py1), narrowPrecisionToFloat(px2),
- narrowPrecisionToFloat(py2), narrowPrecisionToFloat(px3), narrowPrecisionToFloat(py3));
-
- contrlx = xc;
- contrly = yc;
- curx = relative ? curx + tox : tox;
- cury = relative ? cury + toy : toy;
- }
- else
- svgCurveToQuadraticSmooth(narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), !relative);
- break;
- }
- case 'a':
- relative = true;
- case 'A':
- {
- bool largeArc, sweep;
- double angle, rx, ry;
- if (!parseNumber(ptr, end, rx) || !parseNumber(ptr, end, ry)
- || !parseNumber(ptr, end, angle)
- || !parseArcFlag(ptr, end, largeArc) || !parseArcFlag(ptr, end, sweep)
- || !parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy))
- return false;
-
- // Spec: radii are nonnegative numbers
- rx = fabs(rx);
- ry = fabs(ry);
-
- if (process)
- calculateArc(relative, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep);
- else
- svgArcTo(narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), narrowPrecisionToFloat(rx), narrowPrecisionToFloat(ry),
- narrowPrecisionToFloat(angle), largeArc, sweep, !relative);
- break;
- }
- default:
- // FIXME: An error should go to the JavaScript console, or the like.
- return false;
- }
- lastCommand = command;
-
- if (ptr >= end)
- return true;
-
- // Check for remaining coordinates in the current command.
- if ((*ptr == '+' || *ptr == '-' || *ptr == '.' || (*ptr >= '0' && *ptr <= '9'))
- && (command != 'z' && command != 'Z')) {
- if (command == 'M')
- command = 'L';
- else if (command == 'm')
- command = 'l';
- } else
- command = *(ptr++);
-
- if (lastCommand != 'C' && lastCommand != 'c' &&
- lastCommand != 'S' && lastCommand != 's' &&
- lastCommand != 'Q' && lastCommand != 'q' &&
- lastCommand != 'T' && lastCommand != 't') {
- contrlx = curx;
- contrly = cury;
- }
- }
-
- return false;
-}
-
-// This works by converting the SVG arc to "simple" beziers.
-// For each bezier found a svgToCurve call is done.
-// Adapted from Niko's code in kdelibs/kdecore/svgicons.
-// Maybe this can serve in some shared lib? (Rob)
-void SVGPathParser::calculateArc(bool relative, double& curx, double& cury, double angle, double x, double y, double r1, double r2, bool largeArcFlag, bool sweepFlag)
-{
- double sin_th, cos_th;
- double a00, a01, a10, a11;
- double x0, y0, x1, y1, xc, yc;
- double d, sfactor, sfactor_sq;
- double th0, th1, th_arc;
- int i, n_segs;
-
- sin_th = sin(angle * (piDouble / 180.0));
- cos_th = cos(angle * (piDouble / 180.0));
-
- double dx;
-
- if (!relative)
- dx = (curx - x) / 2.0;
- else
- dx = -x / 2.0;
-
- double dy;
-
- if (!relative)
- dy = (cury - y) / 2.0;
- else
- dy = -y / 2.0;
-
- double _x1 = cos_th * dx + sin_th * dy;
- double _y1 = -sin_th * dx + cos_th * dy;
- double Pr1 = r1 * r1;
- double Pr2 = r2 * r2;
- double Px = _x1 * _x1;
- double Py = _y1 * _y1;
-
- // Spec : check if radii are large enough
- double check = Px / Pr1 + Py / Pr2;
- if (check > 1) {
- r1 = r1 * sqrt(check);
- r2 = r2 * sqrt(check);
- }
-
- a00 = cos_th / r1;
- a01 = sin_th / r1;
- a10 = -sin_th / r2;
- a11 = cos_th / r2;
-
- x0 = a00 * curx + a01 * cury;
- y0 = a10 * curx + a11 * cury;
-
- if (!relative)
- x1 = a00 * x + a01 * y;
- else
- x1 = a00 * (curx + x) + a01 * (cury + y);
-
- if (!relative)
- y1 = a10 * x + a11 * y;
- else
- y1 = a10 * (curx + x) + a11 * (cury + y);
-
- /* (x0, y0) is current point in transformed coordinate space.
- (x1, y1) is new point in transformed coordinate space.
-
- The arc fits a unit-radius circle in this space.
- */
-
- d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
-
- sfactor_sq = 1.0 / d - 0.25;
-
- if (sfactor_sq < 0)
- sfactor_sq = 0;
-
- sfactor = sqrt(sfactor_sq);
-
- if (sweepFlag == largeArcFlag)
- sfactor = -sfactor;
-
- xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
- yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
-
- /* (xc, yc) is center of the circle. */
- th0 = atan2(y0 - yc, x0 - xc);
- th1 = atan2(y1 - yc, x1 - xc);
-
- th_arc = th1 - th0;
- if (th_arc < 0 && sweepFlag)
- th_arc += 2 * piDouble;
- else if (th_arc > 0 && !sweepFlag)
- th_arc -= 2 * piDouble;
-
- n_segs = (int) (int) ceil(fabs(th_arc / (piDouble * 0.5 + 0.001)));
-
- for (i = 0; i < n_segs; i++) {
- double sin_th, cos_th;
- double a00, a01, a10, a11;
- double x1, y1, x2, y2, x3, y3;
- double t;
- double th_half;
-
- double _th0 = th0 + i * th_arc / n_segs;
- double _th1 = th0 + (i + 1) * th_arc / n_segs;
-
- sin_th = sin(angle * (piDouble / 180.0));
- cos_th = cos(angle * (piDouble / 180.0));
-
- /* inverse transform compared with rsvg_path_arc */
- a00 = cos_th * r1;
- a01 = -sin_th * r2;
- a10 = sin_th * r1;
- a11 = cos_th * r2;
-
- th_half = 0.5 * (_th1 - _th0);
- t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half);
- x1 = xc + cos(_th0) - t * sin(_th0);
- y1 = yc + sin(_th0) + t * cos(_th0);
- x3 = xc + cos(_th1);
- y3 = yc + sin(_th1);
- x2 = x3 + t * sin(_th1);
- y2 = y3 - t * cos(_th1);
-
- svgCurveToCubic(narrowPrecisionToFloat(a00 * x1 + a01 * y1), narrowPrecisionToFloat(a10 * x1 + a11 * y1),
- narrowPrecisionToFloat(a00 * x2 + a01 * y2), narrowPrecisionToFloat(a10 * x2 + a11 * y2),
- narrowPrecisionToFloat(a00 * x3 + a01 * y3), narrowPrecisionToFloat(a10 * x3 + a11 * y3));
- }
-
- if (!relative)
- curx = x;
- else
- curx += x;
-
- if (!relative)
- cury = y;
- else
- cury += y;
-}
-
-class PathBuilder : private SVGPathParser {
-public:
- bool build(Path* path, const String& d)
- {
- Path temporaryPath;
- m_path = &temporaryPath;
- if (!parseSVG(d, true))
- return false;
- temporaryPath.swap(*path);
- return true;
- }
-
-private:
- virtual void svgMoveTo(double x1, double y1, bool closed, bool abs = true)
- {
- current.setX(narrowPrecisionToFloat(abs ? x1 : current.x() + x1));
- current.setY(narrowPrecisionToFloat(abs ? y1 : current.y() + y1));
- if (closed)
- m_path->closeSubpath();
- m_path->moveTo(current);
- }
- virtual void svgLineTo(double x1, double y1, bool abs = true)
- {
- current.setX(narrowPrecisionToFloat(abs ? x1 : current.x() + x1));
- current.setY(narrowPrecisionToFloat(abs ? y1 : current.y() + y1));
- m_path->addLineTo(current);
- }
- virtual void svgCurveToCubic(double x1, double y1, double x2, double y2, double x, double y, bool abs = true)
- {
- if (!abs) {
- x1 += current.x();
- y1 += current.y();
- x2 += current.x();
- y2 += current.y();
- }
- current.setX(narrowPrecisionToFloat(abs ? x : current.x() + x));
- current.setY(narrowPrecisionToFloat(abs ? y : current.y() + y));
- m_path->addBezierCurveTo(FloatPoint::narrowPrecision(x1, y1), FloatPoint::narrowPrecision(x2, y2), current);
- }
- virtual void svgClosePath()
- {
- m_path->closeSubpath();
- }
-
- Path* m_path;
- FloatPoint current;
-};
-
-bool pathFromSVGData(Path& path, const String& d)
-{
- PathBuilder builder;
- return builder.build(&path, d);
-}
-
-class SVGPathSegListBuilder : private SVGPathParser {
-public:
- bool build(SVGPathSegList* segList, const String& d, bool process)
- {
- bool result = parseSVG(d, process);
- size_t size = m_vector.size();
- for (size_t i = 0; i < size; ++i) {
- ExceptionCode ec;
- segList->appendItem(m_vector[i].release(), ec);
- }
- m_vector.clear();
- return result;
- }
-
-private:
- virtual void svgMoveTo(double x1, double y1, bool, bool abs = true)
- {
- if (abs)
- m_vector.append(SVGPathElement::createSVGPathSegMovetoAbs(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1)));
- else
- m_vector.append(SVGPathElement::createSVGPathSegMovetoRel(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1)));
- }
- virtual void svgLineTo(double x1, double y1, bool abs = true)
- {
- if (abs)
- m_vector.append(SVGPathElement::createSVGPathSegLinetoAbs(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1)));
- else
- m_vector.append(SVGPathElement::createSVGPathSegLinetoRel(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1)));
- }
- virtual void svgLineToHorizontal(double x, bool abs)
- {
- if (abs)
- m_vector.append(SVGPathElement::createSVGPathSegLinetoHorizontalAbs(narrowPrecisionToFloat(x)));
- else
- m_vector.append(SVGPathElement::createSVGPathSegLinetoHorizontalRel(narrowPrecisionToFloat(x)));
- }
- virtual void svgLineToVertical(double y, bool abs)
- {
- if (abs)
- m_vector.append(SVGPathElement::createSVGPathSegLinetoVerticalAbs(narrowPrecisionToFloat(y)));
- else
- m_vector.append(SVGPathElement::createSVGPathSegLinetoVerticalRel(narrowPrecisionToFloat(y)));
- }
- virtual void svgCurveToCubic(double x1, double y1, double x2, double y2, double x, double y, bool abs = true)
- {
- if (abs)
- m_vector.append(SVGPathElement::createSVGPathSegCurvetoCubicAbs(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y),
- narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1),
- narrowPrecisionToFloat(x2), narrowPrecisionToFloat(y2)));
- else
- m_vector.append(SVGPathElement::createSVGPathSegCurvetoCubicRel(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y),
- narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1),
- narrowPrecisionToFloat(x2), narrowPrecisionToFloat(y2)));
- }
- virtual void svgCurveToCubicSmooth(double x, double y, double x2, double y2, bool abs)
- {
- if (abs)
- m_vector.append(SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(narrowPrecisionToFloat(x2), narrowPrecisionToFloat(y2),
- narrowPrecisionToFloat(x), narrowPrecisionToFloat(y)));
- else
- m_vector.append(SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(narrowPrecisionToFloat(x2), narrowPrecisionToFloat(y2),
- narrowPrecisionToFloat(x), narrowPrecisionToFloat(y)));
- }
- virtual void svgCurveToQuadratic(double x, double y, double x1, double y1, bool abs)
- {
- if (abs)
- m_vector.append(SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1),
- narrowPrecisionToFloat(x), narrowPrecisionToFloat(y)));
- else
- m_vector.append(SVGPathElement::createSVGPathSegCurvetoQuadraticRel(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1),
- narrowPrecisionToFloat(x), narrowPrecisionToFloat(y)));
- }
- virtual void svgCurveToQuadraticSmooth(double x, double y, bool abs)
- {
- if (abs)
- m_vector.append(SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y)));
- else
- m_vector.append(SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y)));
- }
- virtual void svgArcTo(double x, double y, double r1, double r2, double angle, bool largeArcFlag, bool sweepFlag, bool abs)
- {
- if (abs)
- m_vector.append(SVGPathElement::createSVGPathSegArcAbs(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y),
- narrowPrecisionToFloat(r1), narrowPrecisionToFloat(r2),
- narrowPrecisionToFloat(angle), largeArcFlag, sweepFlag));
- else
- m_vector.append(SVGPathElement::createSVGPathSegArcRel(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y),
- narrowPrecisionToFloat(r1), narrowPrecisionToFloat(r2),
- narrowPrecisionToFloat(angle), largeArcFlag, sweepFlag));
- }
- virtual void svgClosePath()
- {
- m_vector.append(SVGPathElement::createSVGPathSegClosePath());
- }
-
- Vector<RefPtr<SVGPathSeg> > m_vector;
-};
-
-bool pathSegListFromSVGData(SVGPathSegList* path, const String& d, bool process)
-{
- SVGPathSegListBuilder builder;
- return builder.build(path, d, process);
-}
-
bool parseGlyphName(const String& input, HashSet<String>& values)
{
// FIXME: Parsing error detection is missing.
diff --git a/WebCore/svg/SVGParserUtilities.h b/WebCore/svg/SVGParserUtilities.h
index cd6cbbe..69d6b12 100644
--- a/WebCore/svg/SVGParserUtilities.h
+++ b/WebCore/svg/SVGParserUtilities.h
@@ -30,12 +30,11 @@ typedef Vector<UnicodeRange> UnicodeRanges;
namespace WebCore {
- class Path;
class SVGPointList;
- class SVGPathSegList;
bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip = true);
bool parseNumberOptionalNumber(const String& s, float& h, float& v);
+ bool parseArcFlag(const UChar*& ptr, const UChar* end, bool& flag);
// SVG allows several different whitespace characters:
// http://www.w3.org/TR/SVG/paths.html#PathDataBNF
@@ -65,8 +64,6 @@ namespace WebCore {
}
bool pointsListFromSVGData(SVGPointList* pointsList, const String& points);
- bool pathFromSVGData(Path& path, const String& d);
- bool pathSegListFromSVGData(SVGPathSegList* pathSegList, const String& d, bool process = false);
Vector<String> parseDelimitedString(const String& input, const char seperator);
bool parseKerningUnicodeString(const String& input, UnicodeRanges&, HashSet<String>& stringList);
bool parseGlyphName(const String& input, HashSet<String>& values);
diff --git a/WebCore/svg/SVGPathBuilder.cpp b/WebCore/svg/SVGPathBuilder.cpp
new file mode 100644
index 0000000..916c7d0
--- /dev/null
+++ b/WebCore/svg/SVGPathBuilder.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2002, 2003 The Karbon Developers
+ * 2006 Alexander Kellett <lypanov@kde.org>
+ * 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyrigth (C) 2007, 2009 Apple, Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "SVGPathBuilder.h"
+
+#include "SVGPathParser.h"
+
+namespace WebCore {
+
+SVGPathBuilder::SVGPathBuilder(Path& path)
+ : m_path(path)
+{
+}
+
+bool SVGPathBuilder::build(const String& d)
+{
+ SVGPathParser parser(this);
+ return parser.parsePathDataString(d, true);
+}
+
+void SVGPathBuilder::moveTo(const FloatPoint& point, bool closed, PathCoordinateMode mode)
+{
+ m_current = mode == AbsoluteCoordinates ? point : m_current + point;
+ if (closed)
+ m_path.closeSubpath();
+ m_path.moveTo(m_current);
+}
+
+void SVGPathBuilder::lineTo(const FloatPoint& point, PathCoordinateMode mode)
+{
+ m_current = mode == AbsoluteCoordinates ? point : m_current + point;
+ m_path.addLineTo(m_current);
+}
+
+void SVGPathBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& point, PathCoordinateMode mode)
+{
+ if (mode == RelativeCoordinates) {
+ m_path.addBezierCurveTo(m_current + point1, m_current + point2, m_current + point);
+ m_current += point;
+ } else {
+ m_current = point;
+ m_path.addBezierCurveTo(point1, point2, m_current);
+ }
+}
+
+void SVGPathBuilder::closePath()
+{
+ m_path.closeSubpath();
+}
+
+}
+
+#endif // ENABLE(SVG)
diff --git a/WebCore/svg/SVGPathBuilder.h b/WebCore/svg/SVGPathBuilder.h
new file mode 100644
index 0000000..c47e69d
--- /dev/null
+++ b/WebCore/svg/SVGPathBuilder.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2002, 2003 The Karbon Developers
+ * 2006 Alexander Kellett <lypanov@kde.org>
+ * 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyrigth (C) 2007, 2009 Apple, Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SVGPathBuilder_h
+#define SVGPathBuilder_h
+
+#if ENABLE(SVG)
+#include "FloatPoint.h"
+#include "Path.h"
+#include "SVGPathConsumer.h"
+
+namespace WebCore {
+
+class SVGPathBuilder : private SVGPathConsumer {
+public:
+ SVGPathBuilder(Path&);
+ bool build(const String&);
+
+private:
+ // Used in UnalteredParisng/NormalizedParsing modes.
+ virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode);
+ virtual void lineTo(const FloatPoint&, PathCoordinateMode);
+ virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode);
+ virtual void closePath();
+
+private:
+ // Only used in UnalteredParsing mode.
+ virtual void lineToHorizontal(float, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
+ virtual void lineToVertical(float, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
+ virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
+ virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
+ virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
+ virtual void arcTo(const FloatPoint&, float, float, float, bool, bool, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
+
+ Path& m_path;
+ FloatPoint m_current;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG)
+#endif // SVGPathBuilder_h
diff --git a/WebCore/svg/SVGPathConsumer.h b/WebCore/svg/SVGPathConsumer.h
new file mode 100644
index 0000000..7f2fb39
--- /dev/null
+++ b/WebCore/svg/SVGPathConsumer.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2002, 2003 The Karbon Developers
+ * 2006 Alexander Kellett <lypanov@kde.org>
+ * 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyrigth (C) 2007, 2009 Apple, Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SVGPathConsumer_h
+#define SVGPathConsumer_h
+
+#if ENABLE(SVG)
+#include "FloatPoint.h"
+
+namespace WebCore {
+
+enum PathCoordinateMode {
+ AbsoluteCoordinates,
+ RelativeCoordinates
+};
+
+enum PathParsingMode {
+ NormalizedParsing,
+ UnalteredParsing
+};
+
+class SVGPathConsumer {
+public:
+ // Used in UnalteredParisng/NormalizedParsing modes.
+ virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) = 0;
+ virtual void lineTo(const FloatPoint&, PathCoordinateMode) = 0;
+ virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) = 0;
+ virtual void closePath() = 0;
+
+public:
+ // Only used in UnalteredParsing mode.
+ virtual void lineToHorizontal(float, PathCoordinateMode) = 0;
+ virtual void lineToVertical(float, PathCoordinateMode) = 0;
+ virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) = 0;
+ virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) = 0;
+ virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) = 0;
+ virtual void arcTo(const FloatPoint&, float, float, float, bool largeArcFlag, bool sweepFlag, PathCoordinateMode) = 0;
+
+protected:
+ SVGPathConsumer() { }
+ virtual ~SVGPathConsumer() { }
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG)
+#endif // SVGPathConsumer_h
diff --git a/WebCore/svg/SVGPathElement.cpp b/WebCore/svg/SVGPathElement.cpp
index 40996d1..803ce14 100644
--- a/WebCore/svg/SVGPathElement.cpp
+++ b/WebCore/svg/SVGPathElement.cpp
@@ -25,8 +25,8 @@
#include "Attribute.h"
#include "RenderPath.h"
+#include "RenderSVGResource.h"
#include "SVGNames.h"
-#include "SVGParserUtilities.h"
#include "SVGPathSegArc.h"
#include "SVGPathSegClosePath.h"
#include "SVGPathSegCurvetoCubic.h"
@@ -37,6 +37,7 @@
#include "SVGPathSegLinetoHorizontal.h"
#include "SVGPathSegLinetoVertical.h"
#include "SVGPathSegList.h"
+#include "SVGPathSegListBuilder.h"
#include "SVGPathSegMoveto.h"
#include "SVGSVGElement.h"
@@ -172,7 +173,8 @@ void SVGPathElement::parseMappedAttribute(Attribute* attr)
if (attr->name() == SVGNames::dAttr) {
ExceptionCode ec;
pathSegList()->clear(ec);
- if (!pathSegListFromSVGData(pathSegList(), attr->value(), true))
+ SVGPathSegListBuilder parser(pathSegList());
+ if (!parser.build(attr->value(), NormalizedParsing))
document()->accessSVGExtensions()->reportError("Problem parsing d=\"" + attr->value() + "\"");
} else if (attr->name() == SVGNames::pathLengthAttr) {
setPathLengthBaseValue(attr->value().toFloat());
@@ -199,13 +201,13 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
if (attrName == SVGNames::dAttr) {
renderer->setNeedsPathUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
@@ -213,7 +215,7 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
|| SVGTests::isKnownAttribute(attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
void SVGPathElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGPathParser.cpp b/WebCore/svg/SVGPathParser.cpp
new file mode 100644
index 0000000..3d937c0
--- /dev/null
+++ b/WebCore/svg/SVGPathParser.cpp
@@ -0,0 +1,509 @@
+/*
+ * Copyright (C) 2002, 2003 The Karbon Developers
+ * 2006 Alexander Kellett <lypanov@kde.org>
+ * 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyrigth (C) 2007, 2009 Apple, Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "SVGPathParser.h"
+
+#include "AffineTransform.h"
+#include "SVGParserUtilities.h"
+#include <wtf/MathExtras.h>
+
+static const float gOneOverThree = 1 / 3.f;
+
+namespace WebCore {
+
+SVGPathParser::SVGPathParser(SVGPathConsumer* consumer)
+ : m_consumer(consumer)
+{
+}
+
+SVGPathParser::~SVGPathParser()
+{
+}
+
+void SVGPathParser::parseClosePathSegment()
+{
+ // Reset m_currentPoint for the next path.
+ if (m_normalized)
+ m_currentPoint = m_subPathPoint;
+ m_pathClosed = true;
+ m_consumer->closePath();
+}
+
+bool SVGPathParser::parseMoveToSegment()
+{
+ float toX;
+ float toY;
+ if (!parseNumber(m_ptr, m_end, toX) || !parseNumber(m_ptr, m_end, toY))
+ return false;
+
+ FloatPoint toPoint(toX, toY);
+ if (m_normalized) {
+ if (m_mode == RelativeCoordinates)
+ m_currentPoint += toPoint;
+ else
+ m_currentPoint = toPoint;
+ m_subPathPoint = m_currentPoint;
+ m_consumer->moveTo(m_currentPoint, m_pathClosed, AbsoluteCoordinates);
+ } else
+ m_consumer->moveTo(toPoint, m_pathClosed, m_mode);
+ m_pathClosed = false;
+ return true;
+}
+
+bool SVGPathParser::parseLineToSegment()
+{
+ float toX;
+ float toY;
+ if (!parseNumber(m_ptr, m_end, toX) || !parseNumber(m_ptr, m_end, toY))
+ return false;
+
+ FloatPoint toPoint(toX, toY);
+ if (m_normalized) {
+ if (m_mode == RelativeCoordinates)
+ m_currentPoint += toPoint;
+ else
+ m_currentPoint = toPoint;
+ m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates);
+ } else
+ m_consumer->lineTo(toPoint, m_mode);
+ return true;
+}
+
+bool SVGPathParser::parseLineToHorizontalSegment()
+{
+ float toX;
+ if (!parseNumber(m_ptr, m_end, toX))
+ return false;
+
+ if (m_normalized) {
+ if (m_mode == RelativeCoordinates)
+ m_currentPoint.move(toX, 0);
+ else
+ m_currentPoint.setX(toX);
+ m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates);
+ } else
+ m_consumer->lineToHorizontal(toX, m_mode);
+ return true;
+}
+
+bool SVGPathParser::parseLineToVerticalSegment()
+{
+ float toY;
+ if (!parseNumber(m_ptr, m_end, toY))
+ return false;
+
+ if (m_normalized) {
+ if (m_mode == RelativeCoordinates)
+ m_currentPoint.move(0, toY);
+ else
+ m_currentPoint.setY(toY);
+ m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates);
+ } else
+ m_consumer->lineToVertical(toY, m_mode);
+ return true;
+}
+
+bool SVGPathParser::parseCurveToCubicSegment()
+{
+ float x1;
+ float y1;
+ float x2;
+ float y2;
+ float toX;
+ float toY;
+ if (!parseNumber(m_ptr, m_end, x1)
+ || !parseNumber(m_ptr, m_end, y1)
+ || !parseNumber(m_ptr, m_end, x2)
+ || !parseNumber(m_ptr, m_end, y2)
+ || !parseNumber(m_ptr, m_end, toX)
+ || !parseNumber(m_ptr, m_end, toY))
+ return false;
+
+ FloatPoint point1(x1, y1);
+ FloatPoint point2(x2, y2);
+ FloatPoint point3(toX, toY);
+ if (m_normalized) {
+ if (m_mode == RelativeCoordinates) {
+ point1 += m_currentPoint;
+ point2 += m_currentPoint;
+ point3 += m_currentPoint;
+ }
+ m_consumer->curveToCubic(point1, point2, point3, AbsoluteCoordinates);
+
+ m_controlPoint = point2;
+ m_currentPoint = point3;
+ } else
+ m_consumer->curveToCubic(point1, point2, point3, m_mode);
+ return true;
+}
+
+bool SVGPathParser::parseCurveToCubicSmoothSegment()
+{
+ float x2;
+ float y2;
+ float toX;
+ float toY;
+ if (!parseNumber(m_ptr, m_end, x2)
+ || !parseNumber(m_ptr, m_end, y2)
+ || !parseNumber(m_ptr, m_end, toX)
+ || !parseNumber(m_ptr, m_end, toY))
+ return false;
+
+ if (m_lastCommand != 'c'
+ && m_lastCommand != 'C'
+ && m_lastCommand != 's'
+ && m_lastCommand != 'S')
+ m_controlPoint = m_currentPoint;
+
+ FloatPoint point2(x2, y2);
+ FloatPoint point3(toX, toY);
+ if (m_normalized) {
+ FloatPoint point1 = m_currentPoint;
+ point1.scale(2, 2);
+ point1.move(-m_controlPoint.x(), -m_controlPoint.y());
+ if (m_mode == RelativeCoordinates) {
+ point2 += m_currentPoint;
+ point3 += m_currentPoint;
+ }
+
+ m_consumer->curveToCubic(point1, point2, point3, AbsoluteCoordinates);
+
+ m_controlPoint = point2;
+ m_currentPoint = point3;
+ } else
+ m_consumer->curveToCubicSmooth(point2, point3, m_mode);
+ return true;
+}
+
+bool SVGPathParser::parseCurveToQuadraticSegment()
+{
+ float x1;
+ float y1;
+ float toX;
+ float toY;
+ if (!parseNumber(m_ptr, m_end, x1)
+ || !parseNumber(m_ptr, m_end, y1)
+ || !parseNumber(m_ptr, m_end, toX)
+ || !parseNumber(m_ptr, m_end, toY))
+ return false;
+
+ FloatPoint point3(toX, toY);
+ if (m_normalized) {
+ FloatPoint point1 = m_currentPoint;
+ point1.move(2 * x1, 2 * y1);
+ FloatPoint point2(toX + 2 * x1, toY + 2 * y1);
+ if (m_mode == RelativeCoordinates) {
+ point1.move(2 * m_currentPoint.x(), 2 * m_currentPoint.y());
+ point2.move(3 * m_currentPoint.x(), 3 * m_currentPoint.y());
+ point3 += m_currentPoint;
+ }
+ point1.scale(gOneOverThree, gOneOverThree);
+ point2.scale(gOneOverThree, gOneOverThree);
+
+ m_consumer->curveToCubic(point1, point2, point3, AbsoluteCoordinates);
+
+ m_controlPoint = FloatPoint(x1, y1);
+ if (m_mode == RelativeCoordinates)
+ m_controlPoint += m_currentPoint;
+ m_currentPoint = point3;
+ } else
+ m_consumer->curveToQuadratic(FloatPoint(x1, y1), point3, m_mode);
+ return true;
+}
+
+bool SVGPathParser::parseCurveToQuadraticSmoothSegment()
+{
+ float toX;
+ float toY;
+ if (!parseNumber(m_ptr, m_end, toX) || !parseNumber(m_ptr, m_end, toY))
+ return false;
+ if (m_lastCommand != 'q'
+ && m_lastCommand != 'Q'
+ && m_lastCommand != 't'
+ && m_lastCommand != 'T')
+ m_controlPoint = m_currentPoint;
+
+ if (m_normalized) {
+ FloatPoint cubicPoint = m_currentPoint;
+ cubicPoint.scale(2, 2);
+ cubicPoint.move(-m_controlPoint.x(), -m_controlPoint.y());
+ FloatPoint point1(m_currentPoint.x() + 2 * cubicPoint.x(), m_currentPoint.y() + 2 * cubicPoint.y());
+ FloatPoint point2(toX + 2 * cubicPoint.x(), toY + 2 * cubicPoint.y());
+ FloatPoint point3(toX, toY);
+ if (m_mode == RelativeCoordinates) {
+ point2 += m_currentPoint;
+ point3 += m_currentPoint;
+ }
+ point1.scale(gOneOverThree, gOneOverThree);
+ point2.scale(gOneOverThree, gOneOverThree);
+
+ m_consumer->curveToCubic(point1, point2, point3, AbsoluteCoordinates);
+
+ m_controlPoint = cubicPoint;
+ m_currentPoint = point3;
+ } else
+ m_consumer->curveToQuadraticSmooth(FloatPoint(toX, toY), m_mode);
+ return true;
+}
+
+bool SVGPathParser::parseArcToSegment()
+{
+ bool largeArc;
+ bool sweep;
+ float angle;
+ float rx;
+ float ry;
+ float toX;
+ float toY;
+ if (!parseNumber(m_ptr, m_end, rx)
+ || !parseNumber(m_ptr, m_end, ry)
+ || !parseNumber(m_ptr, m_end, angle)
+ || !parseArcFlag(m_ptr, m_end, largeArc)
+ || !parseArcFlag(m_ptr, m_end, sweep)
+ || !parseNumber(m_ptr, m_end, toX)
+ || !parseNumber(m_ptr, m_end, toY))
+ return false;
+
+ FloatPoint point2 = FloatPoint(toX, toY);
+ // If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a "lineto") joining the endpoints.
+ // http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters
+ rx = fabsf(rx);
+ ry = fabsf(ry);
+ if (!rx || !ry) {
+ if (m_normalized) {
+ if (m_mode == RelativeCoordinates)
+ m_currentPoint += point2;
+ else
+ m_currentPoint = point2;
+ m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates);
+ } else
+ m_consumer->lineTo(point2, m_mode);
+ return true;
+ }
+
+ if (m_normalized) {
+ FloatPoint point1 = m_currentPoint;
+ if (m_mode == RelativeCoordinates)
+ point2 += m_currentPoint;
+ m_currentPoint = point2;
+ return decomposeArcToCubic(angle, rx, ry, point1, point2, largeArc, sweep);
+ }
+ m_consumer->arcTo(point2, rx, ry, angle, largeArc, sweep, m_mode);
+ return true;
+}
+
+bool SVGPathParser::parsePathDataString(const String& s, bool normalized)
+{
+ m_ptr = s.characters();
+ m_end = m_ptr + s.length();
+ m_normalized = normalized;
+
+ m_controlPoint = FloatPoint();
+ m_currentPoint = FloatPoint();
+ m_subPathPoint = FloatPoint();
+ m_pathClosed = true;
+
+ // Skip any leading spaces.
+ if (!skipOptionalSpaces(m_ptr, m_end))
+ return false;
+
+ char command = *(m_ptr++);
+ m_lastCommand = ' ';
+ // Path must start with moveto.
+ if (command != 'm' && command != 'M')
+ return false;
+
+ while (true) {
+ // Skip spaces between command and first coordinate.
+ skipOptionalSpaces(m_ptr, m_end);
+ m_mode = command >= 'a' && command <= 'z' ? RelativeCoordinates : AbsoluteCoordinates;
+ switch (command) {
+ case 'm':
+ case 'M':
+ if (!parseMoveToSegment())
+ return false;
+ break;
+ case 'l':
+ case 'L':
+ if (!parseLineToSegment())
+ return false;
+ break;
+ case 'h':
+ case 'H':
+ if (!parseLineToHorizontalSegment())
+ return false;
+ break;
+ case 'v':
+ case 'V':
+ if (!parseLineToVerticalSegment())
+ return false;
+ break;
+ case 'z':
+ case 'Z':
+ parseClosePathSegment();
+ break;
+ case 'c':
+ case 'C':
+ if (!parseCurveToCubicSegment())
+ return false;
+ break;
+ case 's':
+ case 'S':
+ if (!parseCurveToCubicSmoothSegment())
+ return false;
+ break;
+ case 'q':
+ case 'Q':
+ if (!parseCurveToQuadraticSegment())
+ return false;
+ break;
+ case 't':
+ case 'T':
+ if (!parseCurveToQuadraticSmoothSegment())
+ return false;
+ break;
+ case 'a':
+ case 'A':
+ if (!parseArcToSegment())
+ return false;
+ break;
+ default:
+ return false;
+ }
+ m_lastCommand = command;
+
+ if (m_ptr >= m_end)
+ return true;
+
+ // Check for remaining coordinates in the current command.
+ if ((*m_ptr == '+' || *m_ptr == '-' || *m_ptr == '.' || (*m_ptr >= '0' && *m_ptr <= '9'))
+ && command != 'z' && command != 'Z') {
+ if (command == 'M')
+ command = 'L';
+ else if (command == 'm')
+ command = 'l';
+ } else
+ command = *(m_ptr++);
+
+ if (m_lastCommand != 'C' && m_lastCommand != 'c'
+ && m_lastCommand != 'S' && m_lastCommand != 's'
+ && m_lastCommand != 'Q' && m_lastCommand != 'q'
+ && m_lastCommand != 'T' && m_lastCommand != 't')
+ m_controlPoint = m_currentPoint;
+ }
+
+ return false;
+}
+
+// This works by converting the SVG arc to "simple" beziers.
+// Partly adapted from Niko's code in kdelibs/kdecore/svgicons.
+// See also SVG implementation notes: http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
+bool SVGPathParser::decomposeArcToCubic(float angle, float rx, float ry, FloatPoint& point1, FloatPoint& point2, bool largeArcFlag, bool sweepFlag)
+{
+ FloatSize midPointDistance = point1 - point2;
+ midPointDistance.scale(0.5f);
+
+ AffineTransform pointTransform;
+ pointTransform.rotate(-angle);
+
+ FloatPoint transformedMidPoint = pointTransform.mapPoint(FloatPoint(midPointDistance.width(), midPointDistance.height()));
+ float squareRx = rx * rx;
+ float squareRy = ry * ry;
+ float squareX = transformedMidPoint.x() * transformedMidPoint.x();
+ float squareY = transformedMidPoint.y() * transformedMidPoint.y();
+
+ // Check if the radii are big enough to draw the arc, scale radii if not.
+ // http://www.w3.org/TR/SVG/implnote.html#ArcCorrectionOutOfRangeRadii
+ float radiiScale = squareX / squareRx + squareY / squareRy;
+ if (radiiScale > 1) {
+ rx *= sqrtf(radiiScale);
+ ry *= sqrtf(radiiScale);
+ }
+
+ pointTransform.makeIdentity();
+ pointTransform.scale(1 / rx, 1 / ry);
+ pointTransform.rotate(-angle);
+
+ point1 = pointTransform.mapPoint(point1);
+ point2 = pointTransform.mapPoint(point2);
+ FloatSize delta = point2 - point1;
+
+ float d = delta.width() * delta.width() + delta.height() * delta.height();
+ float scaleFactorSquared = std::max(1 / d - 0.25f, 0.f);
+
+ float scaleFactor = sqrtf(scaleFactorSquared);
+ if (sweepFlag == largeArcFlag)
+ scaleFactor = -scaleFactor;
+
+ delta.scale(scaleFactor);
+ FloatPoint centerPoint = FloatPoint(0.5f * (point1.x() + point2.x()) - delta.height(),
+ 0.5f * (point1.y() + point2.y()) + delta.width());
+
+ float theta1 = atan2f(point1.y() - centerPoint.y(), point1.x() - centerPoint.x());
+ float theta2 = atan2f(point2.y() - centerPoint.y(), point2.x() - centerPoint.x());
+
+ float thetaArc = theta2 - theta1;
+ if (thetaArc < 0 && sweepFlag)
+ thetaArc += 2 * piFloat;
+ else if (thetaArc > 0 && !sweepFlag)
+ thetaArc -= 2 * piFloat;
+
+ pointTransform.makeIdentity();
+ pointTransform.rotate(angle);
+ pointTransform.scale(rx, ry);
+
+ // Some results of atan2 on some platform implementations are not exact enough. So that we get more
+ // cubic curves than expected here. Adding 0.001f reduces the count of sgements to the correct count.
+ int segments = ceilf(fabsf(thetaArc / (piOverTwoFloat + 0.001f)));
+ for (int i = 0; i < segments; ++i) {
+ float startTheta = theta1 + i * thetaArc / segments;
+ float endTheta = theta1 + (i + 1) * thetaArc / segments;
+
+ float t = (8 / 6.f) * tanf(0.25f * (endTheta - startTheta));
+ if (!isfinite(t))
+ return false;
+ float sinStartTheta = sinf(startTheta);
+ float cosStartTheta = cosf(startTheta);
+ float sinEndTheta = sinf(endTheta);
+ float cosEndTheta = cosf(endTheta);
+
+ point1 = FloatPoint(cosStartTheta - t * sinStartTheta, sinStartTheta + t * cosStartTheta);
+ point1.move(centerPoint.x(), centerPoint.y());
+ FloatPoint point3 = FloatPoint(cosEndTheta, sinEndTheta);
+ point3.move(centerPoint.x(), centerPoint.y());
+ point2 = point3;
+ point2.move(t * sinEndTheta, -t * cosEndTheta);
+
+ m_consumer->curveToCubic(pointTransform.mapPoint(point1), pointTransform.mapPoint(point2),
+ pointTransform.mapPoint(point3), AbsoluteCoordinates);
+ }
+ return true;
+}
+
+}
+
+#endif // ENABLE(SVG)
diff --git a/WebCore/svg/SVGPathParser.h b/WebCore/svg/SVGPathParser.h
new file mode 100644
index 0000000..f39094b
--- /dev/null
+++ b/WebCore/svg/SVGPathParser.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2002, 2003 The Karbon Developers
+ * 2006 Alexander Kellett <lypanov@kde.org>
+ * 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyrigth (C) 2007, 2009 Apple, Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SVGPathParser_h
+#define SVGPathParser_h
+
+#if ENABLE(SVG)
+#include "PlatformString.h"
+#include "SVGPathConsumer.h"
+
+namespace WebCore {
+
+class SVGPathParser {
+public:
+ SVGPathParser(SVGPathConsumer*);
+ ~SVGPathParser();
+
+ bool parsePathDataString(const String&, bool normalized = false);
+
+private:
+ bool decomposeArcToCubic(float, float, float, FloatPoint&, FloatPoint&, bool largeArcFlag, bool sweepFlag);
+ void parseClosePathSegment();
+ bool parseMoveToSegment();
+ bool parseLineToSegment();
+ bool parseLineToHorizontalSegment();
+ bool parseLineToVerticalSegment();
+ bool parseCurveToCubicSegment();
+ bool parseCurveToCubicSmoothSegment();
+ bool parseCurveToQuadraticSegment();
+ bool parseCurveToQuadraticSmoothSegment();
+ bool parseArcToSegment();
+
+ SVGPathConsumer* m_consumer;
+ PathCoordinateMode m_mode;
+ const UChar* m_ptr;
+ const UChar* m_end;
+ char m_lastCommand;
+ bool m_normalized;
+ bool m_pathClosed;
+ FloatPoint m_controlPoint;
+ FloatPoint m_currentPoint;
+ FloatPoint m_subPathPoint;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG)
+#endif // SVGPathParser_h
diff --git a/WebCore/svg/SVGPathSegListBuilder.cpp b/WebCore/svg/SVGPathSegListBuilder.cpp
new file mode 100644
index 0000000..4434c2e
--- /dev/null
+++ b/WebCore/svg/SVGPathSegListBuilder.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2002, 2003 The Karbon Developers
+ * 2006 Alexander Kellett <lypanov@kde.org>
+ * 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyrigth (C) 2007, 2009 Apple, Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "SVGPathSegListBuilder.h"
+
+#include "ExceptionCode.h"
+#include "SVGPathElement.h"
+#include "SVGPathParser.h"
+#include "SVGPathSegArc.h"
+#include "SVGPathSegClosePath.h"
+#include "SVGPathSegCurvetoCubic.h"
+#include "SVGPathSegCurvetoCubicSmooth.h"
+#include "SVGPathSegCurvetoQuadratic.h"
+#include "SVGPathSegCurvetoQuadraticSmooth.h"
+#include "SVGPathSegLineto.h"
+#include "SVGPathSegLinetoHorizontal.h"
+#include "SVGPathSegLinetoVertical.h"
+#include "SVGPathSegList.h"
+#include "SVGPathSegMoveto.h"
+
+namespace WebCore {
+
+SVGPathSegListBuilder::SVGPathSegListBuilder(SVGPathSegList* segList)
+ : m_pathSegList(segList)
+{
+}
+
+bool SVGPathSegListBuilder::build(const String& d, PathParsingMode parsingMode)
+{
+ if (!m_pathSegList)
+ return false;
+
+ SVGPathParser parser(this);
+ return parser.parsePathDataString(d, parsingMode == NormalizedParsing);
+}
+
+void SVGPathSegListBuilder::moveTo(const FloatPoint& point, bool, PathCoordinateMode mode)
+{
+ ExceptionCode ec = 0;
+ if (mode == AbsoluteCoordinates)
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegMovetoAbs(point.x(), point.y()), ec);
+ else
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegMovetoRel(point.x(), point.y()), ec);
+ ASSERT(!ec);
+}
+
+void SVGPathSegListBuilder::lineTo(const FloatPoint& point, PathCoordinateMode mode)
+{
+ ExceptionCode ec = 0;
+ if (mode == AbsoluteCoordinates)
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegLinetoAbs(point.x(), point.y()), ec);
+ else
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegLinetoRel(point.x(), point.y()), ec);
+ ASSERT(!ec);
+}
+
+void SVGPathSegListBuilder::lineToHorizontal(float x, PathCoordinateMode mode)
+{
+ ExceptionCode ec = 0;
+ if (mode == AbsoluteCoordinates)
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegLinetoHorizontalAbs(x), ec);
+ else
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegLinetoHorizontalRel(x), ec);
+ ASSERT(!ec);
+}
+
+void SVGPathSegListBuilder::lineToVertical(float y, PathCoordinateMode mode)
+{
+ ExceptionCode ec = 0;
+ if (mode == AbsoluteCoordinates)
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegLinetoVerticalAbs(y), ec);
+ else
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegLinetoVerticalRel(y), ec);
+ ASSERT(!ec);
+}
+
+void SVGPathSegListBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& point, PathCoordinateMode mode)
+{
+ ExceptionCode ec = 0;
+ if (mode == AbsoluteCoordinates)
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegCurvetoCubicAbs(point.x(), point.y(), point1.x(), point1.y(), point2.x(), point2.y()), ec);
+ else
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegCurvetoCubicRel(point.x(), point.y(), point1.x(), point1.y(), point2.x(), point2.y()), ec);
+ ASSERT(!ec);
+}
+
+void SVGPathSegListBuilder::curveToCubicSmooth(const FloatPoint& point, const FloatPoint& point2, PathCoordinateMode mode)
+{
+ ExceptionCode ec = 0;
+ if (mode == AbsoluteCoordinates)
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(point2.x(), point2.y(), point.x(), point.y()), ec);
+ else
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(point2.x(), point2.y(), point.x(), point.y()), ec);
+ ASSERT(!ec);
+}
+
+void SVGPathSegListBuilder::curveToQuadratic(const FloatPoint& point, const FloatPoint& point1, PathCoordinateMode mode)
+{
+ ExceptionCode ec = 0;
+ if (mode == AbsoluteCoordinates)
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(point1.x(), point1.y(), point.x(), point.y()), ec);
+ else
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegCurvetoQuadraticRel(point1.x(), point1.y(), point.x(), point.y()), ec);
+ ASSERT(!ec);
+}
+
+void SVGPathSegListBuilder::curveToQuadraticSmooth(const FloatPoint& point, PathCoordinateMode mode)
+{
+ ExceptionCode ec = 0;
+ if (mode == AbsoluteCoordinates)
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(point.x(), point.y()), ec);
+ else
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(point.x(), point.y()), ec);
+ ASSERT(!ec);
+}
+
+void SVGPathSegListBuilder::arcTo(const FloatPoint& point, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, PathCoordinateMode mode)
+{
+ ExceptionCode ec = 0;
+ if (mode == AbsoluteCoordinates)
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegArcAbs(point.x(), point.y(), r1, r2, angle, largeArcFlag, sweepFlag), ec);
+ else
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegArcRel(point.x(), point.y(), r1, r2, angle, largeArcFlag, sweepFlag), ec);
+ ASSERT(!ec);
+}
+
+void SVGPathSegListBuilder::closePath()
+{
+ ExceptionCode ec = 0;
+ m_pathSegList->appendItem(SVGPathElement::createSVGPathSegClosePath(), ec);
+ ASSERT(!ec);
+}
+
+}
+
+#endif // ENABLE(SVG)
diff --git a/WebCore/svg/SVGPathSegListBuilder.h b/WebCore/svg/SVGPathSegListBuilder.h
new file mode 100644
index 0000000..71d0dde
--- /dev/null
+++ b/WebCore/svg/SVGPathSegListBuilder.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2002, 2003 The Karbon Developers
+ * 2006 Alexander Kellett <lypanov@kde.org>
+ * 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyrigth (C) 2007, 2009 Apple, Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SVGPathSegListBuilder_h
+#define SVGPathSegListBuilder_h
+
+#if ENABLE(SVG)
+#include "FloatPoint.h"
+#include "SVGPathConsumer.h"
+#include "SVGPathSegList.h"
+
+namespace WebCore {
+
+class SVGPathSegListBuilder : private SVGPathConsumer {
+public:
+ SVGPathSegListBuilder(SVGPathSegList*);
+ bool build(const String&, PathParsingMode);
+
+private:
+ // Used in UnalteredParisng/NormalizedParsing modes.
+ virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode);
+ virtual void lineTo(const FloatPoint&, PathCoordinateMode);
+ virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode);
+ virtual void closePath();
+
+private:
+ // Only used in UnalteredParsing mode.
+ virtual void lineToHorizontal(float, PathCoordinateMode);
+ virtual void lineToVertical(float, PathCoordinateMode);
+ virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode);
+ virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode);
+ virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode);
+ virtual void arcTo(const FloatPoint&, float, float, float, bool largeArcFlag, bool sweepFlag, PathCoordinateMode);
+
+ SVGPathSegList* m_pathSegList;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG)
+#endif // SVGPathSegListBuilder_h
diff --git a/WebCore/svg/SVGPolyElement.cpp b/WebCore/svg/SVGPolyElement.cpp
index 6f88b22..2996dd7 100644
--- a/WebCore/svg/SVGPolyElement.cpp
+++ b/WebCore/svg/SVGPolyElement.cpp
@@ -27,6 +27,7 @@
#include "Document.h"
#include "FloatPoint.h"
#include "RenderPath.h"
+#include "RenderSVGResource.h"
#include "SVGNames.h"
#include "SVGParserUtilities.h"
#include "SVGPointList.h"
@@ -94,20 +95,20 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName)
if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (attrName == SVGNames::pointsAttr) {
renderer->setNeedsPathUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (SVGTests::isKnownAttribute(attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
void SVGPolyElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGRectElement.cpp b/WebCore/svg/SVGRectElement.cpp
index 3e559ed..a848246 100644
--- a/WebCore/svg/SVGRectElement.cpp
+++ b/WebCore/svg/SVGRectElement.cpp
@@ -25,6 +25,7 @@
#include "Attribute.h"
#include "RenderPath.h"
+#include "RenderSVGResource.h"
#include "SVGLength.h"
#include "SVGNames.h"
@@ -101,20 +102,20 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (isLengthAttribute) {
renderer->setNeedsPathUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
if (SVGTests::isKnownAttribute(attrName)
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
void SVGRectElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGSVGElement.cpp b/WebCore/svg/SVGSVGElement.cpp
index 6d88c37..c513b98 100644
--- a/WebCore/svg/SVGSVGElement.cpp
+++ b/WebCore/svg/SVGSVGElement.cpp
@@ -35,6 +35,7 @@
#include "FloatRect.h"
#include "FrameView.h"
#include "HTMLNames.h"
+#include "RenderSVGResource.h"
#include "RenderSVGRoot.h"
#include "RenderSVGViewportContainer.h"
#include "SMILTimeContainer.h"
@@ -204,8 +205,8 @@ void SVGSVGElement::setCurrentScale(float scale)
}
m_scale = scale;
- if (renderer())
- renderer()->setNeedsLayout(true);
+ if (RenderObject* object = renderer())
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
}
FloatPoint SVGSVGElement::currentTranslate() const
@@ -320,7 +321,7 @@ void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName)
|| SVGZoomAndPan::isKnownAttribute(attrName)
|| SVGStyledLocatableElement::isKnownAttribute(attrName))
- renderer()->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
}
void SVGSVGElement::synchronizeProperty(const QualifiedName& attrName)
@@ -579,7 +580,9 @@ void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement)
if (viewElement->hasAttribute(SVGNames::zoomAndPanAttr))
currentView()->setZoomAndPan(viewElement->zoomAndPan());
- renderer()->setNeedsLayout(true);
+
+ if (RenderObject* object = renderer())
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
}
void SVGSVGElement::documentWillBecomeInactive()
diff --git a/WebCore/svg/SVGStopElement.cpp b/WebCore/svg/SVGStopElement.cpp
index 672b082..36d4338 100644
--- a/WebCore/svg/SVGStopElement.cpp
+++ b/WebCore/svg/SVGStopElement.cpp
@@ -26,6 +26,7 @@
#include "Attribute.h"
#include "Document.h"
#include "RenderSVGGradientStop.h"
+#include "RenderSVGResource.h"
#include "SVGGradientElement.h"
#include "SVGNames.h"
@@ -33,7 +34,7 @@ namespace WebCore {
SVGStopElement::SVGStopElement(const QualifiedName& tagName, Document* doc)
: SVGStyledElement(tagName, doc)
- , m_offset(0.0f)
+ , m_offset(0)
{
}
@@ -53,6 +54,17 @@ void SVGStopElement::parseMappedAttribute(Attribute* attr)
SVGStyledElement::parseMappedAttribute(attr);
}
+void SVGStopElement::svgAttributeChanged(const QualifiedName& attrName)
+{
+ SVGStyledElement::svgAttributeChanged(attrName);
+
+ if (!renderer())
+ return;
+
+ if (attrName == SVGNames::offsetAttr)
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
+}
+
void SVGStopElement::synchronizeProperty(const QualifiedName& attrName)
{
SVGStyledElement::synchronizeProperty(attrName);
diff --git a/WebCore/svg/SVGStopElement.h b/WebCore/svg/SVGStopElement.h
index db5eff0..96c3294 100644
--- a/WebCore/svg/SVGStopElement.h
+++ b/WebCore/svg/SVGStopElement.h
@@ -33,6 +33,7 @@ namespace WebCore {
virtual ~SVGStopElement();
virtual void parseMappedAttribute(Attribute*);
+ virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
Color stopColorIncludingOpacity() const;
diff --git a/WebCore/svg/SVGStyledElement.cpp b/WebCore/svg/SVGStyledElement.cpp
index 6b55683..6c2993c 100644
--- a/WebCore/svg/SVGStyledElement.cpp
+++ b/WebCore/svg/SVGStyledElement.cpp
@@ -246,14 +246,6 @@ void SVGStyledElement::svgAttributeChanged(const QualifiedName& attrName)
object->toRenderSVGResourceContainer()->idChanged();
}
- if (!document()->parsing() && object) {
- // If we're the child of a resource element, tell the resource (and eventually its resources) that we've changed.
- invalidateResourcesInAncestorChain();
-
- // If we're referencing resources, tell them we've changed.
- RenderSVGResource::invalidateAllResourcesOfRenderer(object);
- }
-
// Invalidate all SVGElementInstances associated with us
SVGElementInstance::invalidateAllInstancesOfElement(this);
}
@@ -266,27 +258,11 @@ void SVGStyledElement::synchronizeProperty(const QualifiedName& attrName)
synchronizeClassName();
}
-void SVGStyledElement::invalidateResourcesInAncestorChain() const
-{
- Node* node = parentNode();
- while (node) {
- if (!node->isSVGElement())
- break;
-
- SVGElement* element = static_cast<SVGElement*>(node);
- if (SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(element->isStyled() ? element : 0)) {
- styledElement->invalidateResourceClients();
-
- // If we found the first resource in the ancestor chain, immediately stop.
- break;
- }
-
- node = node->parentNode();
- }
-}
-
void SVGStyledElement::invalidateResourceClients()
{
+ if (document()->parsing())
+ return;
+
RenderObject* object = renderer();
if (!object)
return;
diff --git a/WebCore/svg/SVGStyledElement.h b/WebCore/svg/SVGStyledElement.h
index dcfc96a..4982908 100644
--- a/WebCore/svg/SVGStyledElement.h
+++ b/WebCore/svg/SVGStyledElement.h
@@ -65,7 +65,6 @@ namespace WebCore {
PassRefPtr<RenderStyle> resolveStyle(RenderStyle* parentStyle);
void invalidateResourceClients();
- void invalidateResourcesInAncestorChain() const;
bool instanceUpdatesBlocked() const;
void setInstanceUpdatesBlocked(bool);
diff --git a/WebCore/svg/SVGTRefElement.cpp b/WebCore/svg/SVGTRefElement.cpp
index 4faa633..4c593ca 100644
--- a/WebCore/svg/SVGTRefElement.cpp
+++ b/WebCore/svg/SVGTRefElement.cpp
@@ -24,6 +24,7 @@
#include "SVGTRefElement.h"
#include "RenderSVGInline.h"
+#include "RenderSVGResource.h"
#include "SVGDocument.h"
#include "SVGNames.h"
#include "Text.h"
@@ -69,7 +70,7 @@ void SVGTRefElement::svgAttributeChanged(const QualifiedName& attrName)
return;
if (SVGURIReference::isKnownAttribute(attrName))
- renderer()->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
}
void SVGTRefElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGTextElement.cpp b/WebCore/svg/SVGTextElement.cpp
index 0aba04b..7269adf 100644
--- a/WebCore/svg/SVGTextElement.cpp
+++ b/WebCore/svg/SVGTextElement.cpp
@@ -26,6 +26,7 @@
#include "AffineTransform.h"
#include "Attribute.h"
#include "FloatRect.h"
+#include "RenderSVGResource.h"
#include "RenderSVGText.h"
#include "SVGLengthList.h"
#include "SVGRenderStyle.h"
@@ -120,7 +121,7 @@ void SVGTextElement::svgAttributeChanged(const QualifiedName& attrName)
if (SVGTransformable::isKnownAttribute(attrName)) {
renderer->setNeedsTransformUpdate();
- renderer->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
}
diff --git a/WebCore/svg/SVGTextPathElement.cpp b/WebCore/svg/SVGTextPathElement.cpp
index 288edfd..732185d 100644
--- a/WebCore/svg/SVGTextPathElement.cpp
+++ b/WebCore/svg/SVGTextPathElement.cpp
@@ -25,6 +25,7 @@
#include "AffineTransform.h"
#include "Attribute.h"
#include "FloatRect.h"
+#include "RenderSVGResource.h"
#include "RenderSVGTextPath.h"
#include "SVGLengthList.h"
#include "SVGPathElement.h"
@@ -82,7 +83,7 @@ void SVGTextPathElement::svgAttributeChanged(const QualifiedName& attrName)
if (attrName == SVGNames::startOffsetAttr
|| SVGTextContentElement::isKnownAttribute(attrName)
|| SVGURIReference::isKnownAttribute(attrName))
- renderer()->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
}
void SVGTextPathElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGTextPositioningElement.cpp b/WebCore/svg/SVGTextPositioningElement.cpp
index ef47322..19f1fbc 100644
--- a/WebCore/svg/SVGTextPositioningElement.cpp
+++ b/WebCore/svg/SVGTextPositioningElement.cpp
@@ -25,6 +25,7 @@
#include "Attribute.h"
#include "RenderObject.h"
+#include "RenderSVGResource.h"
#include "SVGLengthList.h"
#include "SVGNames.h"
#include "SVGNumberList.h"
@@ -75,7 +76,7 @@ void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrNam
return;
if (isKnownAttribute(attrName))
- renderer()->setNeedsLayout(true);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
}
void SVGTextPositioningElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp
index 5ca560a..e42a794 100644
--- a/WebCore/svg/SVGUseElement.cpp
+++ b/WebCore/svg/SVGUseElement.cpp
@@ -32,6 +32,7 @@
#include "HTMLNames.h"
#include "NodeRenderStyle.h"
#include "RegisteredEventListener.h"
+#include "RenderSVGResource.h"
#include "RenderSVGShadowTreeRootContainer.h"
#include "SVGElementInstance.h"
#include "SVGElementInstanceList.h"
@@ -142,7 +143,8 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
if (isXYAttribute || isWidthHeightAttribute)
updateRelativeLengthsInformation();
- if (!renderer())
+ RenderObject* object = renderer();
+ if (!object)
return;
if (SVGURIReference::isKnownAttribute(attrName)) {
@@ -173,8 +175,8 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
}
if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
- renderer()->setNeedsTransformUpdate();
- renderer()->setNeedsLayout(true);
+ object->setNeedsTransformUpdate();
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
return;
}
@@ -256,8 +258,8 @@ void SVGUseElement::updateContainerSizes()
// Update whole subtree, scanning for shadow container elements, that correspond to <svg>/<symbol> tags
updateContainerSize(this, m_targetElementInstance.get());
- if (renderer())
- renderer()->setNeedsLayout(true);
+ if (RenderObject* object = renderer())
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
}
static void updateContainerOffset(SVGElementInstance* targetInstance)
@@ -308,8 +310,8 @@ void SVGUseElement::updateContainerOffsets()
// Update whole subtree, scanning for shadow container elements, marking a cloned use subtree
updateContainerOffset(m_targetElementInstance.get());
- if (renderer())
- renderer()->setNeedsLayout(true);
+ if (RenderObject* object = renderer())
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
}
void SVGUseElement::recalcStyle(StyleChange change)
diff --git a/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp b/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp
index 39b3e57..ddd4928 100644
--- a/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp
@@ -194,13 +194,27 @@ void FEConvolveMatrix::setPreserveAlpha(bool preserveAlpha)
and would make it really hard to understand.
*/
-static ALWAYS_INLINE unsigned char clampRGBAValue(float rgba)
+static ALWAYS_INLINE unsigned char clampRGBAValue(float channel, unsigned char max = 255)
{
- if (rgba <= 0)
+ if (channel <= 0)
return 0;
- if (rgba >= 255)
- return 255;
- return rgba;
+ if (channel >= max)
+ return max;
+ return channel;
+}
+
+template<bool preserveAlphaValues>
+ALWAYS_INLINE void setDestinationPixels(CanvasPixelArray* image, int& pixel, float* totals, float divisor, float bias, CanvasPixelArray* src)
+{
+ unsigned char maxAlpha = preserveAlphaValues ? 255 : clampRGBAValue(totals[3] / divisor + bias);
+ for (int i = 0; i < 3; ++i)
+ image->set(pixel++, clampRGBAValue(totals[i] / divisor + bias, maxAlpha));
+
+ if (preserveAlphaValues) {
+ image->set(pixel, src->get(pixel));
+ ++pixel;
+ } else
+ image->set(pixel++, maxAlpha);
}
// Only for region C
@@ -244,15 +258,7 @@ ALWAYS_INLINE void FEConvolveMatrix::fastSetInteriorPixels(PaintingData& paintin
}
}
- paintingData.dstPixelArray->set(pixel++, clampRGBAValue(totals[0] / m_divisor + paintingData.bias));
- paintingData.dstPixelArray->set(pixel++, clampRGBAValue(totals[1] / m_divisor + paintingData.bias));
- paintingData.dstPixelArray->set(pixel++, clampRGBAValue(totals[2] / m_divisor + paintingData.bias));
- if (!preserveAlphaValues)
- paintingData.dstPixelArray->set(pixel++, clampRGBAValue(totals[3] / m_divisor + paintingData.bias));
- else {
- paintingData.dstPixelArray->set(pixel, paintingData.srcPixelArray->get(pixel));
- ++pixel;
- }
+ setDestinationPixels<preserveAlphaValues>(paintingData.dstPixelArray, pixel, totals, m_divisor, paintingData.bias, paintingData.srcPixelArray);
startKernelPixel += 4;
}
pixel += xIncrease;
@@ -337,15 +343,7 @@ void FEConvolveMatrix::fastSetOuterPixels(PaintingData& paintingData, int x1, in
}
}
- paintingData.dstPixelArray->set(pixel++, clampRGBAValue(totals[0] / m_divisor + paintingData.bias));
- paintingData.dstPixelArray->set(pixel++, clampRGBAValue(totals[1] / m_divisor + paintingData.bias));
- paintingData.dstPixelArray->set(pixel++, clampRGBAValue(totals[2] / m_divisor + paintingData.bias));
- if (!preserveAlphaValues)
- paintingData.dstPixelArray->set(pixel++, clampRGBAValue(totals[3] / m_divisor + paintingData.bias));
- else {
- paintingData.dstPixelArray->set(pixel, paintingData.srcPixelArray->get(pixel));
- ++pixel;
- }
+ setDestinationPixels<preserveAlphaValues>(paintingData.dstPixelArray, pixel, totals, m_divisor, paintingData.bias, paintingData.srcPixelArray);
++startKernelPixelX;
}
pixel += xIncrease;