diff options
author | Russell Brenner <russellbrenner@google.com> | 2010-11-18 17:33:13 -0800 |
---|---|---|
committer | Russell Brenner <russellbrenner@google.com> | 2010-12-02 13:47:21 -0800 |
commit | 6b70adc33054f8aee8c54d0f460458a9df11b8a5 (patch) | |
tree | 103a13998c33944d6ab3b8318c509a037e639460 /WebCore/svg | |
parent | bdf4ebc8e70b2d221b6ee7a65660918ecb1d33aa (diff) | |
download | external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.zip external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.gz external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.bz2 |
Merge WebKit at r72274: Initial merge by git.
Change-Id: Ie51f0b4a16da82942bd516dce59cfb79ebbe25fb
Diffstat (limited to 'WebCore/svg')
74 files changed, 883 insertions, 414 deletions
diff --git a/WebCore/svg/DeprecatedSVGAnimatedPropertyTraits.h b/WebCore/svg/DeprecatedSVGAnimatedPropertyTraits.h index e20a4c7..3e31095 100644 --- a/WebCore/svg/DeprecatedSVGAnimatedPropertyTraits.h +++ b/WebCore/svg/DeprecatedSVGAnimatedPropertyTraits.h @@ -22,26 +22,13 @@ #define DeprecatedSVGAnimatedPropertyTraits_h #if ENABLE(SVG) -#include "PlatformString.h" -#include "SVGTransformList.h" +// FIXME: Remove this file! namespace WebCore { template<typename Type> struct DeprecatedSVGAnimatedPropertyTraits : public Noncopyable { }; -// SVGAnimatedTransformList -template<> -struct DeprecatedSVGAnimatedPropertyTraits<SVGTransformList*> : public Noncopyable { - typedef SVGTransformList* PassType; - typedef SVGTransformList* ReturnType; - typedef RefPtr<SVGTransformList> StoredType; - - static ReturnType null() { return 0; } - static ReturnType toReturnType(const StoredType& type) { return type.get(); } - static String toString(PassType type) { return type ? type->valueAsString() : String(); } -}; - } #endif diff --git a/WebCore/svg/DeprecatedSVGAnimatedTemplate.h b/WebCore/svg/DeprecatedSVGAnimatedTemplate.h index 9258692..7021d12 100644 --- a/WebCore/svg/DeprecatedSVGAnimatedTemplate.h +++ b/WebCore/svg/DeprecatedSVGAnimatedTemplate.h @@ -27,10 +27,10 @@ #include <wtf/Forward.h> #include <wtf/HashMap.h> +// FIXME: Remove this file! namespace WebCore { class SVGElement; - class SVGTransformList; struct DeprecatedSVGAnimatedTypeWrapperKey { // Empty value @@ -151,9 +151,6 @@ namespace WebCore { return wrapper.release(); } - // Common type definitions, to ease IDL generation. - typedef DeprecatedSVGAnimatedTemplate<SVGTransformList*> SVGAnimatedTransformList; - } #endif diff --git a/WebCore/svg/SVGAElement.cpp b/WebCore/svg/SVGAElement.cpp index 8e429d0..8e0e56e 100644 --- a/WebCore/svg/SVGAElement.cpp +++ b/WebCore/svg/SVGAElement.cpp @@ -121,7 +121,7 @@ void SVGAElement::synchronizeProperty(const QualifiedName& attrName) RenderObject* SVGAElement::createRenderer(RenderArena* arena, RenderStyle*) { - if (static_cast<SVGElement*>(parent())->isTextContent()) + if (static_cast<SVGElement*>(parentNode())->isTextContent()) return new (arena) RenderSVGInline(this); return new (arena) RenderSVGTransformableContainer(this); @@ -207,8 +207,8 @@ bool SVGAElement::childShouldCreateRenderer(Node* child) const // The 'a' element may contain any element that its parent may contain, except itself. if (child->hasTagName(SVGNames::aTag)) return false; - if (parent() && parent()->isSVGElement()) - return parent()->childShouldCreateRenderer(child); + if (parentNode() && parentNode()->isSVGElement()) + return parentNode()->childShouldCreateRenderer(child); return SVGElement::childShouldCreateRenderer(child); } diff --git a/WebCore/svg/SVGAnimateTransformElement.cpp b/WebCore/svg/SVGAnimateTransformElement.cpp index 7471ea7..f5d5aa8 100644 --- a/WebCore/svg/SVGAnimateTransformElement.cpp +++ b/WebCore/svg/SVGAnimateTransformElement.cpp @@ -86,15 +86,16 @@ void SVGAnimateTransformElement::parseMappedAttribute(Attribute* attr) } -static PassRefPtr<SVGTransformList> transformListFor(SVGElement* element) +static SVGTransformList* transformListFor(SVGElement* element) { ASSERT(element); if (element->isStyledTransformable()) - return static_cast<SVGStyledTransformableElement*>(element)->transform(); + return &static_cast<SVGStyledTransformableElement*>(element)->transform(); if (element->hasTagName(SVGNames::textTag)) - return static_cast<SVGTextElement*>(element)->transform(); + return &static_cast<SVGTextElement*>(element)->transform(); if (element->hasTagName(SVGNames::linearGradientTag) || element->hasTagName(SVGNames::radialGradientTag)) - return static_cast<SVGGradientElement*>(element)->gradientTransform(); + return &static_cast<SVGGradientElement*>(element)->gradientTransform(); + // FIXME: Handle patternTransform, which is obviously missing! return 0; } @@ -109,9 +110,8 @@ void SVGAnimateTransformElement::resetToBaseValue(const String& baseValue) } if (baseValue.isEmpty()) { - ExceptionCode ec; - RefPtr<SVGTransformList> list = transformListFor(targetElement()); - list->clear(ec); + if (SVGTransformList* list = transformListFor(targetElement())) + list->clear(); } else targetElement()->setAttribute(SVGNames::transformAttr, baseValue); } @@ -121,18 +121,17 @@ void SVGAnimateTransformElement::calculateAnimatedValue(float percentage, unsign if (!hasValidTarget()) return; SVGElement* targetElement = resultElement->targetElement(); - RefPtr<SVGTransformList> transformList = transformListFor(targetElement); + SVGTransformList* transformList = transformListFor(targetElement); ASSERT(transformList); - ExceptionCode ec; if (!isAdditive()) - transformList->clear(ec); + transformList->clear(); if (isAccumulated() && repeat) { SVGTransform accumulatedTransform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(repeat).addToSVGTransform(SVGTransform()); - transformList->appendItem(accumulatedTransform, ec); + transformList->append(accumulatedTransform); } SVGTransform transform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(percentage).addToSVGTransform(m_fromTransform); - transformList->appendItem(transform, ec); + transformList->append(transform); } bool SVGAnimateTransformElement::calculateFromAndToValues(const String& fromString, const String& toString) @@ -181,18 +180,22 @@ void SVGAnimateTransformElement::applyResultsToTarget() } // ...except in case where we have additional instances in <use> trees. + SVGTransformList* transformList = transformListFor(targetElement); + if (!transformList) + return; + const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement(); - RefPtr<SVGTransformList> transformList = transformListFor(targetElement); const HashSet<SVGElementInstance*>::const_iterator end = instances.end(); for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) { SVGElement* shadowTreeElement = (*it)->shadowTreeElement(); ASSERT(shadowTreeElement); if (shadowTreeElement->isStyledTransformable()) - static_cast<SVGStyledTransformableElement*>(shadowTreeElement)->setTransformBaseValue(transformList.get()); + static_cast<SVGStyledTransformableElement*>(shadowTreeElement)->setTransformBaseValue(*transformList); else if (shadowTreeElement->hasTagName(SVGNames::textTag)) - static_cast<SVGTextElement*>(shadowTreeElement)->setTransformBaseValue(transformList.get()); + static_cast<SVGTextElement*>(shadowTreeElement)->setTransformBaseValue(*transformList); else if (shadowTreeElement->hasTagName(SVGNames::linearGradientTag) || shadowTreeElement->hasTagName(SVGNames::radialGradientTag)) - static_cast<SVGGradientElement*>(shadowTreeElement)->setGradientTransformBaseValue(transformList.get()); + static_cast<SVGGradientElement*>(shadowTreeElement)->setGradientTransformBaseValue(*transformList); + // FIXME: Handle patternTransform, obviously missing! if (RenderObject* renderer = shadowTreeElement->renderer()) { renderer->setNeedsTransformUpdate(); RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); diff --git a/WebCore/svg/SVGAnimatedTransformList.h b/WebCore/svg/SVGAnimatedTransformList.h new file mode 100644 index 0000000..dcf87dd --- /dev/null +++ b/WebCore/svg/SVGAnimatedTransformList.h @@ -0,0 +1,33 @@ +/* + * 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 SVGAnimatedTransformList_h +#define SVGAnimatedTransformList_h + +#if ENABLE(SVG) +#include "SVGAnimatedTransformListPropertyTearOff.h" + +namespace WebCore { + +typedef SVGAnimatedTransformListPropertyTearOff SVGAnimatedTransformList; + +} // namespace WebCore + +#endif // ENABLE(SVG) +#endif diff --git a/WebCore/svg/SVGAnimationElement.cpp b/WebCore/svg/SVGAnimationElement.cpp index b5eaafc..25b319e 100644 --- a/WebCore/svg/SVGAnimationElement.cpp +++ b/WebCore/svg/SVGAnimationElement.cpp @@ -382,7 +382,18 @@ void SVGAnimationElement::calculateKeyTimesForCalcModePaced() } static inline double solveEpsilon(double duration) { return 1. / (200. * duration); } - + +unsigned SVGAnimationElement::calculateKeyTimesIndex(float percent) const +{ + unsigned index; + unsigned keyTimesCount = m_keyTimes.size(); + for (index = 1; index < keyTimesCount; ++index) { + if (m_keyTimes[index] >= percent) + break; + } + return --index; +} + float SVGAnimationElement::calculatePercentForSpline(float percent, unsigned splineIndex) const { ASSERT(calcMode() == CalcModeSpline); @@ -398,17 +409,10 @@ float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const { ASSERT(!m_keyPoints.isEmpty()); ASSERT(calcMode() != CalcModePaced); - unsigned keyTimesCount = m_keyTimes.size(); - ASSERT(keyTimesCount > 1); - ASSERT(m_keyPoints.size() == keyTimesCount); - - unsigned index; - for (index = 1; index < keyTimesCount; ++index) { - if (m_keyTimes[index] >= percent) - break; - } - --index; + ASSERT(m_keyTimes.size() > 1); + ASSERT(m_keyPoints.size() == m_keyTimes.size()); + unsigned index = calculateKeyTimesIndex(percent); float fromPercent = m_keyTimes[index]; float toPercent = m_keyTimes[index + 1]; float fromKeyPoint = m_keyPoints[index]; @@ -451,13 +455,7 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float& ASSERT(!keyTimesCount || valuesCount == keyTimesCount); ASSERT(!keyTimesCount || (keyTimesCount > 1 && m_keyTimes[0] == 0)); - unsigned index; - for (index = 1; index < keyTimesCount; ++index) { - if (m_keyTimes[index] >= percent) - break; - } - --index; - + unsigned index = calculateKeyTimesIndex(percent); if (calcMode == CalcModeDiscrete) { if (!keyTimesCount) index = percent == 1.0f ? valuesCount - 1 : static_cast<unsigned>(percent * valuesCount); @@ -510,10 +508,12 @@ void SVGAnimationElement::startedActiveInterval() if (hasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() != m_keyTimes.size()) return; + AnimationMode animationMode = this->animationMode(); CalcMode calcMode = this->calcMode(); if (calcMode == CalcModeSpline) { - unsigned num = m_keySplines.size() + 1; - if ((hasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() != num) || m_values.size() != num) + unsigned splinesCount = m_keySplines.size() + 1; + if ((hasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() != splinesCount) + || (animationMode == ValuesAnimation && m_values.size() != splinesCount)) return; } @@ -521,7 +521,6 @@ void SVGAnimationElement::startedActiveInterval() String to = toValue(); String by = byValue(); SVGElement* target = targetElement(); - AnimationMode animationMode = this->animationMode(); if (animationMode == NoAnimation) return; if (animationMode == FromToAnimation) { @@ -558,6 +557,7 @@ void SVGAnimationElement::updateAnimation(float percent, unsigned repeat, SVGSMI return; float effectivePercent; + CalcMode mode = calcMode(); if (animationMode() == ValuesAnimation) { String from; String to; @@ -569,9 +569,11 @@ void SVGAnimationElement::updateAnimation(float percent, unsigned repeat, SVGSMI m_lastValuesAnimationFrom = from; m_lastValuesAnimationTo = to; } - } else if (!m_keyPoints.isEmpty() && calcMode() != CalcModePaced) + } else if (!m_keyPoints.isEmpty() && mode != CalcModePaced) effectivePercent = calculatePercentFromKeyPoints(percent); - else + else if (m_keyPoints.isEmpty() && mode == CalcModeSpline && m_keyTimes.size() > 1) + effectivePercent = calculatePercentForSpline(percent, calculateKeyTimesIndex(percent)); + else effectivePercent = percent; calculateAnimatedValue(effectivePercent, repeat, resultElement); diff --git a/WebCore/svg/SVGAnimationElement.h b/WebCore/svg/SVGAnimationElement.h index 2e11fe6..367e63f 100644 --- a/WebCore/svg/SVGAnimationElement.h +++ b/WebCore/svg/SVGAnimationElement.h @@ -104,6 +104,7 @@ namespace WebCore { float calculatePercentFromKeyPoints(float percent) const; void currentValuesFromKeyPoints(float percent, float& effectivePercent, String& from, String& to) const; float calculatePercentForSpline(float percent, unsigned splineIndex) const; + unsigned calculateKeyTimesIndex(float percent) const; // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGAnimationElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) diff --git a/WebCore/svg/SVGCircleElement.cpp b/WebCore/svg/SVGCircleElement.cpp index eb38b87..a2c6a8d 100644 --- a/WebCore/svg/SVGCircleElement.cpp +++ b/WebCore/svg/SVGCircleElement.cpp @@ -77,6 +77,9 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName) if (isLengthAttribute) updateRelativeLengthsInformation(); + if (SVGTests::handleAttributeChange(this, attrName)) + return; + RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer()); if (!renderer) return; @@ -93,8 +96,7 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName) return; } - if (SVGTests::isKnownAttribute(attrName) - || SVGLangSpace::isKnownAttribute(attrName) + if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); } diff --git a/WebCore/svg/SVGElement.cpp b/WebCore/svg/SVGElement.cpp index 6c2c4a2..3e9bda0 100644 --- a/WebCore/svg/SVGElement.cpp +++ b/WebCore/svg/SVGElement.cpp @@ -347,13 +347,6 @@ void SVGElement::updateAnimatedSVGAttribute(const QualifiedName& name) const clearIsSynchronizingSVGAttributes(); } -ContainerNode* SVGElement::eventParentNode() -{ - if (ContainerNode* shadowParent = shadowParentNode()) - return shadowParent; - return StyledElement::eventParentNode(); -} - } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGElement.h b/WebCore/svg/SVGElement.h index 517515f..96e7fd7 100644 --- a/WebCore/svg/SVGElement.h +++ b/WebCore/svg/SVGElement.h @@ -99,8 +99,6 @@ namespace WebCore { virtual bool isSupported(StringImpl* feature, StringImpl* version) const; - virtual ContainerNode* eventParentNode(); - virtual bool needsPendingResourceHandling() const { return true; } virtual void buildPendingResource() { } diff --git a/WebCore/svg/SVGEllipseElement.cpp b/WebCore/svg/SVGEllipseElement.cpp index 7615a24..5726c53 100644 --- a/WebCore/svg/SVGEllipseElement.cpp +++ b/WebCore/svg/SVGEllipseElement.cpp @@ -82,6 +82,9 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName) if (isLengthAttribute) updateRelativeLengthsInformation(); + + if (SVGTests::handleAttributeChange(this, attrName)) + return; RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer()); if (!renderer) @@ -99,8 +102,7 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName) return; } - if (SVGTests::isKnownAttribute(attrName) - || SVGLangSpace::isKnownAttribute(attrName) + if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); } diff --git a/WebCore/svg/SVGFEDisplacementMapElement.cpp b/WebCore/svg/SVGFEDisplacementMapElement.cpp index ea8a7b8..ba3311b 100644 --- a/WebCore/svg/SVGFEDisplacementMapElement.cpp +++ b/WebCore/svg/SVGFEDisplacementMapElement.cpp @@ -69,6 +69,18 @@ void SVGFEDisplacementMapElement::parseMappedAttribute(Attribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFEDisplacementMapElement::svgAttributeChanged(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); + + if (attrName == SVGNames::xChannelSelectorAttr + || attrName == SVGNames::yChannelSelectorAttr + || attrName == SVGNames::inAttr + || attrName == SVGNames::in2Attr + || attrName == SVGNames::scaleAttr) + invalidate(); +} + void SVGFEDisplacementMapElement::synchronizeProperty(const QualifiedName& attrName) { SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); diff --git a/WebCore/svg/SVGFEDisplacementMapElement.h b/WebCore/svg/SVGFEDisplacementMapElement.h index a2c9e43..8131d82 100644 --- a/WebCore/svg/SVGFEDisplacementMapElement.h +++ b/WebCore/svg/SVGFEDisplacementMapElement.h @@ -36,6 +36,7 @@ private: SVGFEDisplacementMapElement(const QualifiedName& tagName, Document*); virtual void parseMappedAttribute(Attribute*); + virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*); diff --git a/WebCore/svg/SVGFEImageElement.cpp b/WebCore/svg/SVGFEImageElement.cpp index 0ea7933..1db8edb 100644 --- a/WebCore/svg/SVGFEImageElement.cpp +++ b/WebCore/svg/SVGFEImageElement.cpp @@ -90,6 +90,14 @@ void SVGFEImageElement::parseMappedAttribute(Attribute* attr) } } +void SVGFEImageElement::svgAttributeChanged(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); + + if (attrName == SVGNames::preserveAspectRatioAttr) + invalidate(); +} + void SVGFEImageElement::synchronizeProperty(const QualifiedName& attrName) { SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); diff --git a/WebCore/svg/SVGFEImageElement.h b/WebCore/svg/SVGFEImageElement.h index 0dcf2c8..0b9c5d8 100644 --- a/WebCore/svg/SVGFEImageElement.h +++ b/WebCore/svg/SVGFEImageElement.h @@ -48,6 +48,7 @@ private: SVGFEImageElement(const QualifiedName&, Document*); virtual void parseMappedAttribute(Attribute*); + virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); virtual void notifyFinished(CachedResource*); diff --git a/WebCore/svg/SVGFELightElement.cpp b/WebCore/svg/SVGFELightElement.cpp index 315aa29..7fed774 100644 --- a/WebCore/svg/SVGFELightElement.cpp +++ b/WebCore/svg/SVGFELightElement.cpp @@ -78,8 +78,8 @@ void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName) || attrName == SVGNames::pointsAtZAttr || attrName == SVGNames::specularExponentAttr || attrName == SVGNames::limitingConeAngleAttr) { - if (ContainerNode* parentNode = parent()) { - RenderObject* renderer = parentNode->renderer(); + if (ContainerNode* parent = parentNode()) { + RenderObject* renderer = parent->renderer(); if (renderer && renderer->isSVGResourceFilterPrimitive()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); } @@ -131,8 +131,8 @@ void SVGFELightElement::childrenChanged(bool changedByParser, Node* beforeChange SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (!changedByParser) { - if (ContainerNode* parentNode = parent()) { - RenderObject* renderer = parentNode->renderer(); + if (ContainerNode* parent = parentNode()) { + RenderObject* renderer = parent->renderer(); if (renderer && renderer->isSVGResourceFilterPrimitive()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); } diff --git a/WebCore/svg/SVGFEMergeNodeElement.cpp b/WebCore/svg/SVGFEMergeNodeElement.cpp index ee1ac3a..54bb2fe 100644 --- a/WebCore/svg/SVGFEMergeNodeElement.cpp +++ b/WebCore/svg/SVGFEMergeNodeElement.cpp @@ -55,11 +55,11 @@ void SVGFEMergeNodeElement::svgAttributeChanged(const QualifiedName& attrName) if (attrName != SVGNames::inAttr) return; - ContainerNode* parentNode = parent(); - if (!parentNode) + ContainerNode* parent = parentNode(); + if (!parent) return; - RenderObject* renderer = parentNode->renderer(); + RenderObject* renderer = parent->renderer(); if (!renderer || !renderer->isSVGResourceFilterPrimitive()) return; diff --git a/WebCore/svg/SVGFETileElement.cpp b/WebCore/svg/SVGFETileElement.cpp index 9664490..590b6b8 100644 --- a/WebCore/svg/SVGFETileElement.cpp +++ b/WebCore/svg/SVGFETileElement.cpp @@ -47,6 +47,14 @@ void SVGFETileElement::parseMappedAttribute(Attribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFETileElement::svgAttributeChanged(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); + + if (attrName == SVGNames::inAttr) + invalidate(); +} + void SVGFETileElement::synchronizeProperty(const QualifiedName& attrName) { SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); diff --git a/WebCore/svg/SVGFETileElement.h b/WebCore/svg/SVGFETileElement.h index ffa9d81..b0c97d2 100644 --- a/WebCore/svg/SVGFETileElement.h +++ b/WebCore/svg/SVGFETileElement.h @@ -35,6 +35,7 @@ private: SVGFETileElement(const QualifiedName&, Document*); virtual void parseMappedAttribute(Attribute*); + virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*); diff --git a/WebCore/svg/SVGForeignObjectElement.cpp b/WebCore/svg/SVGForeignObjectElement.cpp index e4f7096..d21172a 100644 --- a/WebCore/svg/SVGForeignObjectElement.cpp +++ b/WebCore/svg/SVGForeignObjectElement.cpp @@ -81,6 +81,9 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName) if (isLengthAttribute) updateRelativeLengthsInformation(); + if (SVGTests::handleAttributeChange(this, attrName)) + return; + RenderObject* renderer = this->renderer(); if (!renderer) return; @@ -92,7 +95,6 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName) } if (isLengthAttribute - || SVGTests::isKnownAttribute(attrName) || SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); diff --git a/WebCore/svg/SVGGElement.cpp b/WebCore/svg/SVGGElement.cpp index a455cd5..b6b4a70 100644 --- a/WebCore/svg/SVGGElement.cpp +++ b/WebCore/svg/SVGGElement.cpp @@ -55,6 +55,9 @@ void SVGGElement::svgAttributeChanged(const QualifiedName& attrName) { SVGStyledTransformableElement::svgAttributeChanged(attrName); + if (SVGTests::handleAttributeChange(this, attrName)) + return; + RenderObject* renderer = this->renderer(); if (!renderer) return; @@ -65,8 +68,7 @@ void SVGGElement::svgAttributeChanged(const QualifiedName& attrName) return; } - if (SVGTests::isKnownAttribute(attrName) - || SVGLangSpace::isKnownAttribute(attrName) + if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); } diff --git a/WebCore/svg/SVGGradientElement.cpp b/WebCore/svg/SVGGradientElement.cpp index ca61088..337944b 100644 --- a/WebCore/svg/SVGGradientElement.cpp +++ b/WebCore/svg/SVGGradientElement.cpp @@ -41,7 +41,6 @@ namespace WebCore { SVGGradientElement::SVGGradientElement(const QualifiedName& tagName, Document* document) : SVGStyledElement(tagName, document) , m_gradientUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - , m_gradientTransform(SVGTransformList::create(SVGNames::gradientTransformAttr)) { } @@ -53,11 +52,12 @@ void SVGGradientElement::parseMappedAttribute(Attribute* attr) else if (attr->value() == "objectBoundingBox") setGradientUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); } else if (attr->name() == SVGNames::gradientTransformAttr) { - SVGTransformList* gradientTransforms = gradientTransformBaseValue(); - if (!SVGTransformable::parseTransformAttribute(gradientTransforms, attr->value())) { - ExceptionCode ec = 0; - gradientTransforms->clear(ec); - } + SVGTransformList newList; + if (!SVGTransformable::parseTransformAttribute(newList, attr->value())) + newList.clear(); + + detachAnimatedGradientTransformListWrappers(newList.size()); + gradientTransformBaseValue() = newList; } else if (attr->name() == SVGNames::spreadMethodAttr) { if (attr->value() == "reflect") setSpreadMethodBaseValue(SpreadMethodReflect); diff --git a/WebCore/svg/SVGGradientElement.h b/WebCore/svg/SVGGradientElement.h index 6e23608..1b28e22 100644 --- a/WebCore/svg/SVGGradientElement.h +++ b/WebCore/svg/SVGGradientElement.h @@ -24,6 +24,7 @@ #if ENABLE(SVG) #include "Gradient.h" #include "SVGAnimatedPropertyMacros.h" +#include "SVGAnimatedTransformList.h" #include "SVGExternalResourcesRequired.h" #include "SVGStyledElement.h" #include "SVGTransformList.h" @@ -51,7 +52,7 @@ namespace WebCore { DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGGradientElement, SVGNames::spreadMethodAttr, int, SpreadMethod, spreadMethod) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGGradientElement, SVGNames::gradientUnitsAttr, int, GradientUnits, gradientUnits) - DECLARE_ANIMATED_PROPERTY(SVGGradientElement, SVGNames::gradientTransformAttr, SVGTransformList*, GradientTransform, gradientTransform) + DECLARE_ANIMATED_TRANSFORM_LIST_PROPERTY_NEW(SVGGradientElement, SVGNames::gradientTransformAttr, SVGTransformList, GradientTransform, gradientTransform) // SVGURIReference DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGGradientElement, XLinkNames::hrefAttr, String, Href, href) diff --git a/WebCore/svg/SVGImageElement.cpp b/WebCore/svg/SVGImageElement.cpp index fcfa54f..3eb64db 100644 --- a/WebCore/svg/SVGImageElement.cpp +++ b/WebCore/svg/SVGImageElement.cpp @@ -98,6 +98,9 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName) if (isLengthAttribute) updateRelativeLengthsInformation(); + if (SVGTests::handleAttributeChange(this, attrName)) + return; + RenderObject* renderer = this->renderer(); if (!renderer) return; @@ -115,7 +118,6 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName) } if (attrName == SVGNames::preserveAspectRatioAttr - || SVGTests::isKnownAttribute(attrName) || SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); diff --git a/WebCore/svg/SVGLength.cpp b/WebCore/svg/SVGLength.cpp index f8381bf..8168cf6 100644 --- a/WebCore/svg/SVGLength.cpp +++ b/WebCore/svg/SVGLength.cpp @@ -347,7 +347,7 @@ bool SVGLength::determineViewport(const SVGElement* context, float& width, float } // Resolve value against enclosing non-SVG RenderBox - if (!context->parent() || context->parent()->isSVGElement()) + if (!context->parentNode() || context->parentNode()->isSVGElement()) return false; RenderObject* renderer = context->renderer(); diff --git a/WebCore/svg/SVGLineElement.cpp b/WebCore/svg/SVGLineElement.cpp index 4ee5f0d..ac461fe 100644 --- a/WebCore/svg/SVGLineElement.cpp +++ b/WebCore/svg/SVGLineElement.cpp @@ -79,6 +79,9 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName) if (isLengthAttribute) updateRelativeLengthsInformation(); + if (SVGTests::handleAttributeChange(this, attrName)) + return; + RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer()); if (!renderer) return; @@ -95,8 +98,7 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName) return; } - if (SVGTests::isKnownAttribute(attrName) - || SVGLangSpace::isKnownAttribute(attrName) + if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); } diff --git a/WebCore/svg/SVGLinearGradientElement.cpp b/WebCore/svg/SVGLinearGradientElement.cpp index 840a31e..fa3e40c 100644 --- a/WebCore/svg/SVGLinearGradientElement.cpp +++ b/WebCore/svg/SVGLinearGradientElement.cpp @@ -127,8 +127,11 @@ void SVGLinearGradientElement::collectGradientAttributes(LinearGradientAttribute if (!attributes.hasBoundingBoxMode() && current->hasAttribute(SVGNames::gradientUnitsAttr)) attributes.setBoundingBoxMode(current->gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); - if (!attributes.hasGradientTransform() && current->hasAttribute(SVGNames::gradientTransformAttr)) - attributes.setGradientTransform(current->gradientTransform()->consolidate().matrix()); + if (!attributes.hasGradientTransform() && current->hasAttribute(SVGNames::gradientTransformAttr)) { + AffineTransform transform; + current->gradientTransform().concatenate(transform); + attributes.setGradientTransform(transform); + } if (!attributes.hasStops()) { const Vector<Gradient::ColorStop>& stops(current->buildStops()); diff --git a/WebCore/svg/SVGMatrix.h b/WebCore/svg/SVGMatrix.h new file mode 100644 index 0000000..807b703 --- /dev/null +++ b/WebCore/svg/SVGMatrix.h @@ -0,0 +1,131 @@ +/* + * 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 SVGMatrix_h +#define SVGMatrix_h + +#if ENABLE(SVG) +#include "AffineTransform.h" +#include "SVGException.h" + +namespace WebCore { + +// Only used in the bindings. +class SVGMatrix : public AffineTransform { +public: + SVGMatrix() { } + SVGMatrix(const AffineTransform& other) + : AffineTransform(other) + { + } + + SVGMatrix(double a, double b, double c, double d, double e, double f) + : AffineTransform(a, b, c, d, e, f) + { + } + + SVGMatrix translate(double tx, double ty) + { + AffineTransform copy = *this; + copy.translate(tx, ty); + return static_cast<SVGMatrix>(copy); + } + + SVGMatrix scale(double s) + { + AffineTransform copy = *this; + copy.scale(s, s); + return static_cast<SVGMatrix>(copy); + } + + SVGMatrix scaleNonUniform(double sx, double sy) + { + AffineTransform copy = *this; + copy.scale(sx, sy); + return static_cast<SVGMatrix>(copy); + } + + SVGMatrix rotate(double d) + { + AffineTransform copy = *this; + copy.rotate(d); + return static_cast<SVGMatrix>(copy); + } + + SVGMatrix flipX() + { + AffineTransform copy = *this; + copy.flipX(); + return static_cast<SVGMatrix>(copy); + } + + SVGMatrix flipY() + { + AffineTransform copy = *this; + copy.flipY(); + return static_cast<SVGMatrix>(copy); + } + + SVGMatrix skewX(double angle) + { + AffineTransform copy = *this; + copy.skewX(angle); + return static_cast<SVGMatrix>(copy); + } + + SVGMatrix skewY(double angle) + { + AffineTransform copy = *this; + copy.skewY(angle); + return static_cast<SVGMatrix>(copy); + } + + // SVGMatrix::multiply needs to call SVGMatrix::multLeft. + SVGMatrix multiply(const SVGMatrix& other) + { + AffineTransform copy = *this; + copy.multLeft(static_cast<const AffineTransform&>(other)); + return static_cast<SVGMatrix>(copy); + } + + SVGMatrix inverse(ExceptionCode& ec) const + { + AffineTransform transform = AffineTransform::inverse(); + if (!isInvertible()) + ec = SVGException::SVG_MATRIX_NOT_INVERTABLE; + + return transform; + } + + SVGMatrix rotateFromVector(double x, double y, ExceptionCode& ec) + { + if (!x || !y) + ec = SVGException::SVG_INVALID_VALUE_ERR; + + AffineTransform copy = *this; + copy.rotateFromVector(x, y); + return static_cast<SVGMatrix>(copy); + } + +}; + +} // namespace WebCore + +#endif // ENABLE(SVG) +#endif diff --git a/WebCore/svg/SVGMatrix.idl b/WebCore/svg/SVGMatrix.idl index c6e996d..270a62c 100644 --- a/WebCore/svg/SVGMatrix.idl +++ b/WebCore/svg/SVGMatrix.idl @@ -22,29 +22,29 @@ module svg { - interface [Conditional=SVG, PODType=AffineTransform] SVGMatrix { + interface [Conditional=SVG] SVGMatrix { // FIXME: these attributes should all be floats but since we implement // AffineTransform with doubles setting these as doubles makes more sense. - attribute double a; - attribute double b; - attribute double c; - attribute double d; - attribute double e; - attribute double f; + attribute [StrictTypeChecking] double a; + attribute [StrictTypeChecking] double b; + attribute [StrictTypeChecking] double c; + attribute [StrictTypeChecking] double d; + attribute [StrictTypeChecking] double e; + attribute [StrictTypeChecking] double f; - [Custom] SVGMatrix multiply(in SVGMatrix secondMatrix); - [Custom] SVGMatrix inverse() + [StrictTypeChecking, RequiresAllArguments=Raise] SVGMatrix multiply(in SVGMatrix secondMatrix); + SVGMatrix inverse() raises(SVGException); - [Immutable] SVGMatrix translate(in float x, in float y); - [Immutable] SVGMatrix scale(in float scaleFactor); - [Immutable] SVGMatrix scaleNonUniform(in float scaleFactorX, in float scaleFactorY); - [Immutable] SVGMatrix rotate(in float angle); - [Custom] SVGMatrix rotateFromVector(in float x, in float y) + [Immutable, StrictTypeChecking, RequiresAllArguments=Raise] SVGMatrix translate(in float x, in float y); + [Immutable, StrictTypeChecking, RequiresAllArguments=Raise] SVGMatrix scale(in float scaleFactor); + [Immutable, StrictTypeChecking, RequiresAllArguments=Raise] SVGMatrix scaleNonUniform(in float scaleFactorX, in float scaleFactorY); + [Immutable, StrictTypeChecking, RequiresAllArguments=Raise] SVGMatrix rotate(in float angle); + [StrictTypeChecking, RequiresAllArguments=Raise] SVGMatrix rotateFromVector(in float x, in float y) raises(SVGException); [Immutable] SVGMatrix flipX(); [Immutable] SVGMatrix flipY(); - [Immutable] SVGMatrix skewX(in float angle); - [Immutable] SVGMatrix skewY(in float angle); + [Immutable, StrictTypeChecking, RequiresAllArguments=Raise] SVGMatrix skewX(in float angle); + [Immutable, StrictTypeChecking, RequiresAllArguments=Raise] SVGMatrix skewY(in float angle); }; } diff --git a/WebCore/svg/SVGPathElement.cpp b/WebCore/svg/SVGPathElement.cpp index 920e947..8f8bef9 100644 --- a/WebCore/svg/SVGPathElement.cpp +++ b/WebCore/svg/SVGPathElement.cpp @@ -201,6 +201,9 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName) { SVGStyledTransformableElement::svgAttributeChanged(attrName); + if (SVGTests::handleAttributeChange(this, attrName)) + return; + RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer()); if (!renderer) return; @@ -218,7 +221,6 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName) } if (attrName == SVGNames::pathLengthAttr - || SVGTests::isKnownAttribute(attrName) || SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); diff --git a/WebCore/svg/SVGPatternElement.cpp b/WebCore/svg/SVGPatternElement.cpp index 0f3b5d4..229e1db 100644 --- a/WebCore/svg/SVGPatternElement.cpp +++ b/WebCore/svg/SVGPatternElement.cpp @@ -57,7 +57,6 @@ inline SVGPatternElement::SVGPatternElement(const QualifiedName& tagName, Docume , m_height(LengthModeHeight) , m_patternUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) , m_patternContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) - , m_patternTransform(SVGTransformList::create(SVGNames::patternTransformAttr)) { } @@ -79,11 +78,12 @@ void SVGPatternElement::parseMappedAttribute(Attribute* attr) else if (attr->value() == "objectBoundingBox") setPatternContentUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); } else if (attr->name() == SVGNames::patternTransformAttr) { - SVGTransformList* patternTransforms = patternTransformBaseValue(); - if (!SVGTransformable::parseTransformAttribute(patternTransforms, attr->value())) { - ExceptionCode ec = 0; - patternTransforms->clear(ec); - } + SVGTransformList newList; + if (!SVGTransformable::parseTransformAttribute(newList, attr->value())) + newList.clear(); + + detachAnimatedPatternTransformListWrappers(newList.size()); + patternTransformBaseValue() = newList; } else if (attr->name() == SVGNames::xAttr) setXBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::yAttr) @@ -224,8 +224,11 @@ void SVGPatternElement::collectPatternAttributes(PatternAttributes& attributes) if (!attributes.hasBoundingBoxModeContent() && current->hasAttribute(SVGNames::patternContentUnitsAttr)) attributes.setBoundingBoxModeContent(current->patternContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); - if (!attributes.hasPatternTransform() && current->hasAttribute(SVGNames::patternTransformAttr)) - attributes.setPatternTransform(current->patternTransform()->consolidate().matrix()); + if (!attributes.hasPatternTransform() && current->hasAttribute(SVGNames::patternTransformAttr)) { + AffineTransform transform; + current->patternTransform().concatenate(transform); + attributes.setPatternTransform(transform); + } if (!attributes.hasPatternContentElement() && current->hasChildNodes()) attributes.setPatternContentElement(current); diff --git a/WebCore/svg/SVGPatternElement.h b/WebCore/svg/SVGPatternElement.h index ce63a22..37f91ca 100644 --- a/WebCore/svg/SVGPatternElement.h +++ b/WebCore/svg/SVGPatternElement.h @@ -24,6 +24,7 @@ #if ENABLE(SVG) #include "SVGAnimatedLength.h" #include "SVGAnimatedPropertyMacros.h" +#include "SVGAnimatedTransformList.h" #include "SVGExternalResourcesRequired.h" #include "SVGFitToViewBox.h" #include "SVGLangSpace.h" @@ -70,7 +71,7 @@ namespace WebCore { DECLARE_ANIMATED_PROPERTY_NEW(SVGPatternElement, SVGNames::heightAttr, SVGLength, Height, height) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGPatternElement, SVGNames::patternUnitsAttr, int, PatternUnits, patternUnits) DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGPatternElement, SVGNames::patternContentUnitsAttr, int, PatternContentUnits, patternContentUnits) - DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::patternTransformAttr, SVGTransformList*, PatternTransform, patternTransform) + DECLARE_ANIMATED_TRANSFORM_LIST_PROPERTY_NEW(SVGPatternElement, SVGNames::patternTransformAttr, SVGTransformList, PatternTransform, patternTransform) // SVGURIReference DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGPatternElement, XLinkNames::hrefAttr, String, Href, href) diff --git a/WebCore/svg/SVGPoint.idl b/WebCore/svg/SVGPoint.idl index 19c6292..f6d2514 100644 --- a/WebCore/svg/SVGPoint.idl +++ b/WebCore/svg/SVGPoint.idl @@ -26,7 +26,7 @@ module svg { attribute [StrictTypeChecking] float x; attribute [StrictTypeChecking] float y; - SVGPoint matrixTransform(in SVGMatrix matrix); + [StrictTypeChecking, RequiresAllArguments=Raise] SVGPoint matrixTransform(in SVGMatrix matrix); }; } diff --git a/WebCore/svg/SVGPolyElement.cpp b/WebCore/svg/SVGPolyElement.cpp index 7b95a32..211dd58 100644 --- a/WebCore/svg/SVGPolyElement.cpp +++ b/WebCore/svg/SVGPolyElement.cpp @@ -66,6 +66,9 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName) { SVGStyledTransformableElement::svgAttributeChanged(attrName); + if (SVGTests::handleAttributeChange(this, attrName)) + return; + RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer()); if (!renderer) return; @@ -82,8 +85,7 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName) return; } - if (SVGTests::isKnownAttribute(attrName) - || SVGLangSpace::isKnownAttribute(attrName) + if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); } diff --git a/WebCore/svg/SVGRadialGradientElement.cpp b/WebCore/svg/SVGRadialGradientElement.cpp index 584b1b6..aaf32bc 100644 --- a/WebCore/svg/SVGRadialGradientElement.cpp +++ b/WebCore/svg/SVGRadialGradientElement.cpp @@ -137,8 +137,11 @@ void SVGRadialGradientElement::collectGradientAttributes(RadialGradientAttribute if (!attributes.hasBoundingBoxMode() && current->hasAttribute(SVGNames::gradientUnitsAttr)) attributes.setBoundingBoxMode(current->gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); - if (!attributes.hasGradientTransform() && current->hasAttribute(SVGNames::gradientTransformAttr)) - attributes.setGradientTransform(current->gradientTransform()->consolidate().matrix()); + if (!attributes.hasGradientTransform() && current->hasAttribute(SVGNames::gradientTransformAttr)) { + AffineTransform transform; + current->gradientTransform().concatenate(transform); + attributes.setGradientTransform(transform); + } if (!attributes.hasStops()) { const Vector<Gradient::ColorStop>& stops(current->buildStops()); diff --git a/WebCore/svg/SVGRectElement.cpp b/WebCore/svg/SVGRectElement.cpp index 46ed8de..c3ff3cb 100644 --- a/WebCore/svg/SVGRectElement.cpp +++ b/WebCore/svg/SVGRectElement.cpp @@ -94,6 +94,9 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) if (isLengthAttribute) updateRelativeLengthsInformation(); + if (SVGTests::handleAttributeChange(this, attrName)) + return; + RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer()); if (!renderer) return; @@ -110,8 +113,7 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) return; } - if (SVGTests::isKnownAttribute(attrName) - || SVGLangSpace::isKnownAttribute(attrName) + if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); } diff --git a/WebCore/svg/SVGSVGElement.cpp b/WebCore/svg/SVGSVGElement.cpp index 314f522..e90fba4 100644 --- a/WebCore/svg/SVGSVGElement.cpp +++ b/WebCore/svg/SVGSVGElement.cpp @@ -91,6 +91,18 @@ SVGSVGElement::~SVGSVGElement() document()->accessSVGExtensions()->removeTimeContainer(this); } +void SVGSVGElement::willMoveToNewOwnerDocument() +{ + document()->unregisterForDocumentActivationCallbacks(this); + SVGStyledLocatableElement::willMoveToNewOwnerDocument(); +} + +void SVGSVGElement::didMoveToNewOwnerDocument() +{ + document()->registerForDocumentActivationCallbacks(this); + SVGStyledLocatableElement::didMoveToNewOwnerDocument(); +} + const AtomicString& SVGSVGElement::contentScriptType() const { DEFINE_STATIC_LOCAL(const AtomicString, defaultValue, ("text/ecmascript")); @@ -319,11 +331,13 @@ void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName) updateRelativeLengthsInformation(); } + if (SVGTests::handleAttributeChange(this, attrName)) + return; + if (!renderer()) return; if (updateRelativeLengths - || SVGTests::isKnownAttribute(attrName) || SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName) || SVGZoomAndPan::isKnownAttribute(attrName) @@ -437,9 +451,9 @@ FloatPoint SVGSVGElement::createSVGPoint() return FloatPoint(); } -AffineTransform SVGSVGElement::createSVGMatrix() +SVGMatrix SVGSVGElement::createSVGMatrix() { - return AffineTransform(); + return SVGMatrix(); } FloatRect SVGSVGElement::createSVGRect() @@ -452,9 +466,9 @@ SVGTransform SVGSVGElement::createSVGTransform() return SVGTransform(SVGTransform::SVG_TRANSFORM_MATRIX); } -SVGTransform SVGSVGElement::createSVGTransformFromMatrix(const AffineTransform& matrix) +SVGTransform SVGSVGElement::createSVGTransformFromMatrix(const SVGMatrix& matrix) { - return SVGTransform(matrix); + return SVGTransform(static_cast<const AffineTransform&>(matrix)); } AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const @@ -570,8 +584,13 @@ AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float vie viewBoxRect = viewBox(); AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(viewBoxRect, preserveAspectRatio(), viewWidth, viewHeight); - if (useCurrentView() && currentView()) - return currentView()->transform()->concatenate().matrix() * ctm; + if (useCurrentView() && currentView()) { + AffineTransform transform; + if (!currentView()->transform().concatenate(transform)) + return ctm; + + return transform * ctm; + } return ctm; } diff --git a/WebCore/svg/SVGSVGElement.h b/WebCore/svg/SVGSVGElement.h index dca3ac2..f73fb3f 100644 --- a/WebCore/svg/SVGSVGElement.h +++ b/WebCore/svg/SVGSVGElement.h @@ -35,6 +35,7 @@ namespace WebCore { class SVGAngle; class SVGLength; + class SVGMatrix; class SVGTransform; class SVGViewSpec; class SVGViewElement; @@ -108,10 +109,10 @@ namespace WebCore { static SVGLength createSVGLength(); static SVGAngle createSVGAngle(); static FloatPoint createSVGPoint(); - static AffineTransform createSVGMatrix(); + static SVGMatrix createSVGMatrix(); static FloatRect createSVGRect(); static SVGTransform createSVGTransform(); - static SVGTransform createSVGTransformFromMatrix(const AffineTransform&); + static SVGTransform createSVGTransformFromMatrix(const SVGMatrix&); AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const; @@ -121,6 +122,10 @@ namespace WebCore { Element* getElementById(const AtomicString&) const; + protected: + virtual void willMoveToNewOwnerDocument(); + virtual void didMoveToNewOwnerDocument(); + private: SVGSVGElement(const QualifiedName&, Document*); virtual ~SVGSVGElement(); diff --git a/WebCore/svg/SVGScriptElement.cpp b/WebCore/svg/SVGScriptElement.cpp index 6532ac2..9146ddc 100644 --- a/WebCore/svg/SVGScriptElement.cpp +++ b/WebCore/svg/SVGScriptElement.cpp @@ -31,21 +31,15 @@ namespace WebCore { -inline SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document* document, bool createdByParser) +inline SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document* document, bool createdByParser, bool isEvaluated) : SVGElement(tagName, document) - , m_data(this, this) + , ScriptElement(this, createdByParser, isEvaluated) { - m_data.setCreatedByParser(createdByParser); } PassRefPtr<SVGScriptElement> SVGScriptElement::create(const QualifiedName& tagName, Document* document, bool createdByParser) { - return adoptRef(new SVGScriptElement(tagName, document, createdByParser)); -} - -String SVGScriptElement::scriptContent() const -{ - return m_data.scriptContent(); + return adoptRef(new SVGScriptElement(tagName, document, createdByParser, false)); } void SVGScriptElement::parseMappedAttribute(Attribute* attr) @@ -69,13 +63,13 @@ void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName) SVGElement::svgAttributeChanged(attrName); if (SVGURIReference::isKnownAttribute(attrName)) - handleSourceAttribute(m_data, href()); + handleSourceAttribute(href()); else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) { // Handle dynamic updates of the 'externalResourcesRequired' attribute. Only possible case: changing from 'true' to 'false' // causes an immediate dispatch of the SVGLoad event. If the attribute value was 'false' before inserting the script element // in the document, the SVGLoad event has already been dispatched. - if (!externalResourcesRequiredBaseValue() && !m_data.haveFiredLoadEvent() && !m_data.createdByParser()) { - m_data.setHaveFiredLoadEvent(true); + if (!externalResourcesRequiredBaseValue() && !haveFiredLoadEvent() && !createdByParser()) { + setHaveFiredLoadEvent(true); ASSERT(haveLoadedRequiredResources()); sendSVGLoadEventIfPossible(); @@ -102,14 +96,14 @@ void SVGScriptElement::synchronizeProperty(const QualifiedName& attrName) void SVGScriptElement::insertedIntoDocument() { SVGElement::insertedIntoDocument(); - ScriptElement::insertedIntoDocument(m_data, sourceAttributeValue()); + ScriptElement::insertedIntoDocument(sourceAttributeValue()); - if (m_data.createdByParser()) + if (createdByParser()) return; // Eventually send SVGLoad event now for the dynamically inserted script element if (!externalResourcesRequiredBaseValue()) { - m_data.setHaveFiredLoadEvent(true); + setHaveFiredLoadEvent(true); sendSVGLoadEventIfPossible(); } } @@ -117,12 +111,12 @@ void SVGScriptElement::insertedIntoDocument() void SVGScriptElement::removedFromDocument() { SVGElement::removedFromDocument(); - ScriptElement::removedFromDocument(m_data); + ScriptElement::removedFromDocument(); } void SVGScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - ScriptElement::childrenChanged(m_data); + ScriptElement::childrenChanged(); SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); } @@ -133,12 +127,12 @@ bool SVGScriptElement::isURLAttribute(Attribute* attr) const void SVGScriptElement::finishParsingChildren() { - ScriptElement::finishParsingChildren(m_data, sourceAttributeValue()); + ScriptElement::finishParsingChildren(sourceAttributeValue()); SVGElement::finishParsingChildren(); // A SVGLoad event has been fired by SVGElement::finishParsingChildren. if (!externalResourcesRequiredBaseValue()) - m_data.setHaveFiredLoadEvent(true); + setHaveFiredLoadEvent(true); } String SVGScriptElement::type() const @@ -151,11 +145,6 @@ void SVGScriptElement::setType(const String& type) m_type = type; } -String SVGScriptElement::scriptCharset() const -{ - return m_data.scriptCharset(); -} - void SVGScriptElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const { SVGElement::addSubresourceAttributeURLs(urls); @@ -165,7 +154,7 @@ void SVGScriptElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) cons bool SVGScriptElement::haveLoadedRequiredResources() { - return !externalResourcesRequiredBaseValue() || m_data.haveFiredLoadEvent(); + return !externalResourcesRequiredBaseValue() || haveFiredLoadEvent(); } String SVGScriptElement::sourceAttributeValue() const @@ -212,9 +201,9 @@ void SVGScriptElement::dispatchLoadEvent() { bool externalResourcesRequired = externalResourcesRequiredBaseValue(); - if (m_data.createdByParser()) - ASSERT(externalResourcesRequired != m_data.haveFiredLoadEvent()); - else if (m_data.haveFiredLoadEvent()) { + if (createdByParser()) + ASSERT(externalResourcesRequired != haveFiredLoadEvent()); + else if (haveFiredLoadEvent()) { // If we've already fired an load event and externalResourcesRequired is set to 'true' // externalResourcesRequired has been modified while loading the <script>. Don't dispatch twice. if (externalResourcesRequired) @@ -226,10 +215,10 @@ void SVGScriptElement::dispatchLoadEvent() // SVG fires the SVGLoad event immediately after parsing the <script> element, if externalResourcesRequired // is set to 'false', otherwhise it dispatches the 'SVGLoad' event just after loading the remote resource. if (externalResourcesRequired) { - ASSERT(!m_data.haveFiredLoadEvent()); + ASSERT(!haveFiredLoadEvent()); // Dispatch SVGLoad event - m_data.setHaveFiredLoadEvent(true); + setHaveFiredLoadEvent(true); ASSERT(haveLoadedRequiredResources()); sendSVGLoadEventIfPossible(); @@ -241,9 +230,9 @@ void SVGScriptElement::dispatchErrorEvent() dispatchEvent(Event::create(eventNames().errorEvent, true, false)); } -bool SVGScriptElement::shouldExecuteAsJavaScript() const +PassRefPtr<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren() const { - return m_data.shouldExecuteAsJavaScript(); + return adoptRef(new SVGScriptElement(tagQName(), document(), false, isEvaluated())); } } diff --git a/WebCore/svg/SVGScriptElement.h b/WebCore/svg/SVGScriptElement.h index e8695fb..7532bf2 100644 --- a/WebCore/svg/SVGScriptElement.h +++ b/WebCore/svg/SVGScriptElement.h @@ -41,9 +41,7 @@ namespace WebCore { void setType(const String&); private: - SVGScriptElement(const QualifiedName&, Document*, bool createdByParser); - - virtual String scriptContent() const; + SVGScriptElement(const QualifiedName&, Document*, bool createdByParser, bool isEvaluated); virtual void parseMappedAttribute(Attribute*); virtual void insertedIntoDocument(); @@ -55,12 +53,8 @@ namespace WebCore { virtual bool isURLAttribute(Attribute*) const; virtual void finishParsingChildren(); - virtual String scriptCharset() const; - virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const; - virtual bool shouldExecuteAsJavaScript() const; - virtual bool haveLoadedRequiredResources(); virtual String sourceAttributeValue() const; @@ -75,13 +69,14 @@ namespace WebCore { virtual void dispatchLoadEvent(); virtual void dispatchErrorEvent(); + PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() const; + // SVGURIReference DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGScriptElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired DECLARE_ANIMATED_STATIC_PROPERTY_NEW(SVGScriptElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) - ScriptElementData m_data; String m_type; }; diff --git a/WebCore/svg/SVGStyleElement.cpp b/WebCore/svg/SVGStyleElement.cpp index 4a80319..042af1c 100644 --- a/WebCore/svg/SVGStyleElement.cpp +++ b/WebCore/svg/SVGStyleElement.cpp @@ -40,6 +40,12 @@ inline SVGStyleElement::SVGStyleElement(const QualifiedName& tagName, Document* { } +SVGStyleElement::~SVGStyleElement() +{ + if (m_sheet) + m_sheet->clearOwnerNode(); +} + PassRefPtr<SVGStyleElement> SVGStyleElement::create(const QualifiedName& tagName, Document* document, bool createdByParser) { return adoptRef(new SVGStyleElement(tagName, document, createdByParser)); @@ -114,11 +120,6 @@ void SVGStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); } -StyleSheet* SVGStyleElement::sheet() -{ - return StyleElement::sheet(this); -} - } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGStyleElement.h b/WebCore/svg/SVGStyleElement.h index bb46549..acf358e 100644 --- a/WebCore/svg/SVGStyleElement.h +++ b/WebCore/svg/SVGStyleElement.h @@ -33,8 +33,9 @@ class SVGStyleElement : public SVGElement , public StyleElement { public: static PassRefPtr<SVGStyleElement> create(const QualifiedName&, Document*, bool createdByParser); + virtual ~SVGStyleElement(); - StyleSheet* sheet(); + using StyleElement::sheet; virtual const AtomicString& type() const; void setType(const AtomicString&, ExceptionCode&); diff --git a/WebCore/svg/SVGStyledElement.cpp b/WebCore/svg/SVGStyledElement.cpp index 64030bc..d5ef486 100644 --- a/WebCore/svg/SVGStyledElement.cpp +++ b/WebCore/svg/SVGStyledElement.cpp @@ -362,14 +362,14 @@ void SVGStyledElement::updateRelativeLengthsInformation(bool hasRelativeLengths, } // Find first styled parent node, and notify it that we've changed our relative length state. - Node* node = parent(); + ContainerNode* node = parentNode(); while (node) { if (!node->isSVGElement()) break; SVGElement* element = static_cast<SVGElement*>(node); if (!element->isStyled()) { - node = node->parent(); + node = node->parentNode(); continue; } diff --git a/WebCore/svg/SVGStyledTransformableElement.cpp b/WebCore/svg/SVGStyledTransformableElement.cpp index 87d812c..e5cd42b 100644 --- a/WebCore/svg/SVGStyledTransformableElement.cpp +++ b/WebCore/svg/SVGStyledTransformableElement.cpp @@ -34,7 +34,6 @@ namespace WebCore { SVGStyledTransformableElement::SVGStyledTransformableElement(const QualifiedName& tagName, Document* document) : SVGStyledLocatableElement(tagName, document) - , m_transform(SVGTransformList::create(SVGNames::transformAttr)) { } @@ -54,9 +53,11 @@ AffineTransform SVGStyledTransformableElement::getScreenCTM(StyleUpdateStrategy AffineTransform SVGStyledTransformableElement::animatedLocalTransform() const { - return m_supplementalTransform ? *m_supplementalTransform * transform()->concatenate().matrix() : transform()->concatenate().matrix(); + AffineTransform matrix; + transform().concatenate(matrix); + return m_supplementalTransform ? *m_supplementalTransform * matrix : matrix; } - + AffineTransform* SVGStyledTransformableElement::supplementalTransform() { if (!m_supplementalTransform) @@ -67,11 +68,11 @@ AffineTransform* SVGStyledTransformableElement::supplementalTransform() void SVGStyledTransformableElement::parseMappedAttribute(Attribute* attr) { if (SVGTransformable::isKnownAttribute(attr->name())) { - SVGTransformList* localTransforms = transformBaseValue(); - if (!SVGTransformable::parseTransformAttribute(localTransforms, attr->value())) { - ExceptionCode ec = 0; - localTransforms->clear(ec); - } + SVGTransformList newList; + if (!SVGTransformable::parseTransformAttribute(newList, attr->value())) + newList.clear(); + detachAnimatedTransformListWrappers(newList.size()); + transformBaseValue() = newList; } else SVGStyledLocatableElement::parseMappedAttribute(attr); } diff --git a/WebCore/svg/SVGStyledTransformableElement.h b/WebCore/svg/SVGStyledTransformableElement.h index f6309dd..54907c1 100644 --- a/WebCore/svg/SVGStyledTransformableElement.h +++ b/WebCore/svg/SVGStyledTransformableElement.h @@ -60,7 +60,7 @@ protected: virtual void parseMappedAttribute(Attribute*); virtual void synchronizeProperty(const QualifiedName&); - DECLARE_ANIMATED_PROPERTY(SVGStyledTransformableElement, SVGNames::transformAttr, SVGTransformList*, Transform, transform) + DECLARE_ANIMATED_TRANSFORM_LIST_PROPERTY_NEW(SVGStyledTransformableElement, SVGNames::transformAttr, SVGTransformList, Transform, transform) private: virtual bool isStyledTransformable() const { return true; } diff --git a/WebCore/svg/SVGTests.cpp b/WebCore/svg/SVGTests.cpp index 3317964..2b9cb14 100644 --- a/WebCore/svg/SVGTests.cpp +++ b/WebCore/svg/SVGTests.cpp @@ -26,6 +26,7 @@ #include "Attribute.h" #include "DOMImplementation.h" #include "Language.h" +#include "SVGElement.h" #include "SVGNames.h" #include "SVGStringList.h" @@ -82,13 +83,34 @@ bool SVGTests::parseMappedAttribute(Attribute* attr) return false; } -bool SVGTests::isKnownAttribute(const QualifiedName& attrName) +static bool knownAttribute(const QualifiedName& attrName) { return attrName == SVGNames::requiredFeaturesAttr || attrName == SVGNames::requiredExtensionsAttr || attrName == SVGNames::systemLanguageAttr; } +bool SVGTests::isKnownAttribute(const QualifiedName& attrName) +{ + return knownAttribute(attrName); +} + +bool SVGTests::handleAttributeChange(const SVGElement* targetElement, const QualifiedName& attrName) +{ + if (!knownAttribute(attrName)) + return false; + if (!targetElement->inDocument()) + return false; + SVGElement* svgElement = const_cast<SVGElement*>(targetElement); + ASSERT(svgElement); + bool valid = svgElement->isValid(); + if (valid && !svgElement->attached()) + svgElement->attach(); + if (!valid && svgElement->attached()) + svgElement->detach(); + return true; +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGTests.h b/WebCore/svg/SVGTests.h index f662e9a..8cba9d2 100644 --- a/WebCore/svg/SVGTests.h +++ b/WebCore/svg/SVGTests.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> + * Copyright (C) 2004, 2005, 2006, 2010 Rob Buis <buis@kde.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -28,6 +28,7 @@ namespace WebCore { class Attribute; class QualifiedName; +class SVGElement; class SVGTests { public: @@ -41,6 +42,8 @@ public: bool parseMappedAttribute(Attribute*); bool isKnownAttribute(const QualifiedName&); + static bool handleAttributeChange(const SVGElement*, const QualifiedName&); + protected: SVGTests(); diff --git a/WebCore/svg/SVGTextContentElement.cpp b/WebCore/svg/SVGTextContentElement.cpp index cdb9d81..0cbcc9a 100644 --- a/WebCore/svg/SVGTextContentElement.cpp +++ b/WebCore/svg/SVGTextContentElement.cpp @@ -201,11 +201,20 @@ void SVGTextContentElement::synchronizeProperty(const QualifiedName& attrName) synchronizeExternalResourcesRequired(); } +void SVGTextContentElement::svgAttributeChanged(const QualifiedName& attrName) +{ + SVGStyledElement::svgAttributeChanged(attrName); + + if (SVGTests::handleAttributeChange(this, attrName)) + return; + + // FIXME: also handle attribute changes for lengthAdjust and textLength +} + bool SVGTextContentElement::isKnownAttribute(const QualifiedName& attrName) { return (attrName.matches(SVGNames::lengthAdjustAttr) || attrName.matches(SVGNames::textLengthAttr) || - SVGTests::isKnownAttribute(attrName) || SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName) || SVGStyledElement::isKnownAttribute(attrName)); diff --git a/WebCore/svg/SVGTextContentElement.h b/WebCore/svg/SVGTextContentElement.h index d3aa061..fd2e003 100644 --- a/WebCore/svg/SVGTextContentElement.h +++ b/WebCore/svg/SVGTextContentElement.h @@ -64,6 +64,7 @@ namespace WebCore { virtual bool isValid() const { return SVGTests::isValid(); } virtual void parseMappedAttribute(Attribute*); + virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); virtual bool selfHasRelativeLengths() const; diff --git a/WebCore/svg/SVGTextElement.cpp b/WebCore/svg/SVGTextElement.cpp index c8f280e..bfa36c8 100644 --- a/WebCore/svg/SVGTextElement.cpp +++ b/WebCore/svg/SVGTextElement.cpp @@ -38,7 +38,6 @@ namespace WebCore { inline SVGTextElement::SVGTextElement(const QualifiedName& tagName, Document* doc) : SVGTextPositioningElement(tagName, doc) , SVGTransformable() - , m_transform(SVGTransformList::create(SVGNames::transformAttr)) { } @@ -50,11 +49,12 @@ PassRefPtr<SVGTextElement> SVGTextElement::create(const QualifiedName& tagName, void SVGTextElement::parseMappedAttribute(Attribute* attr) { if (SVGTransformable::isKnownAttribute(attr->name())) { - SVGTransformList* localTransforms = transformBaseValue(); - if (!SVGTransformable::parseTransformAttribute(localTransforms, attr->value())) { - ExceptionCode ec = 0; - localTransforms->clear(ec); - } + SVGTransformList newList; + if (!SVGTransformable::parseTransformAttribute(newList, attr->value())) + newList.clear(); + + detachAnimatedTransformListWrappers(newList.size()); + transformBaseValue() = newList; } else SVGTextPositioningElement::parseMappedAttribute(attr); } @@ -86,7 +86,9 @@ AffineTransform SVGTextElement::getScreenCTM(StyleUpdateStrategy styleUpdateStra AffineTransform SVGTextElement::animatedLocalTransform() const { - return m_supplementalTransform ? transform()->concatenate().matrix() * *m_supplementalTransform : transform()->concatenate().matrix(); + AffineTransform matrix; + transform().concatenate(matrix); + return m_supplementalTransform ? *m_supplementalTransform * matrix : matrix; } AffineTransform* SVGTextElement::supplementalTransform() diff --git a/WebCore/svg/SVGTextElement.h b/WebCore/svg/SVGTextElement.h index 00afa59..3bfee46 100644 --- a/WebCore/svg/SVGTextElement.h +++ b/WebCore/svg/SVGTextElement.h @@ -22,6 +22,7 @@ #define SVGTextElement_h #if ENABLE(SVG) +#include "SVGAnimatedTransformList.h" #include "SVGTextPositioningElement.h" #include "SVGTransformable.h" @@ -54,7 +55,7 @@ namespace WebCore { virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); - DECLARE_ANIMATED_PROPERTY(SVGTextElement, SVGNames::transformAttr, SVGTransformList*, Transform, transform) + DECLARE_ANIMATED_TRANSFORM_LIST_PROPERTY_NEW(SVGTextElement, SVGNames::transformAttr, SVGTransformList, Transform, transform) // Used by <animateMotion> OwnPtr<AffineTransform> m_supplementalTransform; diff --git a/WebCore/svg/SVGTransform.cpp b/WebCore/svg/SVGTransform.cpp index 86774db..c39fe39 100644 --- a/WebCore/svg/SVGTransform.cpp +++ b/WebCore/svg/SVGTransform.cpp @@ -19,17 +19,17 @@ */ #include "config.h" -#if ENABLE(SVG) +#if ENABLE(SVG) #include "FloatPoint.h" #include "FloatSize.h" #include "SVGAngle.h" #include "SVGSVGElement.h" #include "SVGTransform.h" -#include <math.h> +#include <wtf/MathExtras.h> -using namespace WebCore; +namespace WebCore { SVGTransform::SVGTransform() : m_type(SVG_TRANSFORM_UNKNOWN) @@ -40,8 +40,6 @@ SVGTransform::SVGTransform() SVGTransform::SVGTransform(SVGTransformType type) : m_type(type) , m_angle(0) - , m_center(FloatPoint()) - , m_matrix(AffineTransform()) { } @@ -52,37 +50,20 @@ SVGTransform::SVGTransform(const AffineTransform& matrix) { } -bool SVGTransform::isValid() -{ - return (m_type != SVG_TRANSFORM_UNKNOWN); -} - -SVGTransform::SVGTransformType SVGTransform::type() const -{ - return m_type; -} - -AffineTransform SVGTransform::matrix() const -{ - return m_matrix; -} - -float SVGTransform::angle() const +void SVGTransform::setMatrix(const AffineTransform& matrix) { - return m_angle; -} - -FloatPoint SVGTransform::rotationCenter() const -{ - return m_center; + m_type = SVG_TRANSFORM_MATRIX; + m_angle = 0; + m_matrix = matrix; } -void SVGTransform::setMatrix(AffineTransform matrix) +void SVGTransform::updateMatrix() { + // The underlying matrix has been changed, alter the transformation type. + // Spec: In case the matrix object is changed directly (i.e., without using the methods on the SVGTransform interface itself) + // then the type of the SVGTransform changes to SVG_TRANSFORM_MATRIX. m_type = SVG_TRANSFORM_MATRIX; m_angle = 0; - - m_matrix = matrix; } void SVGTransform::setTranslate(float tx, float ty) @@ -145,5 +126,6 @@ void SVGTransform::setSkewY(float angle) m_matrix.skewY(angle); } -#endif // ENABLE(SVG) +} // namespace WebCore +#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGTransform.h b/WebCore/svg/SVGTransform.h index db6a42f..36dd038 100644 --- a/WebCore/svg/SVGTransform.h +++ b/WebCore/svg/SVGTransform.h @@ -22,67 +22,70 @@ #define SVGTransform_h #if ENABLE(SVG) -#include "AffineTransform.h" #include "FloatPoint.h" +#include "SVGMatrix.h" namespace WebCore { - - class FloatSize; - - class SVGTransform { - public: - enum SVGTransformType { - SVG_TRANSFORM_UNKNOWN = 0, - SVG_TRANSFORM_MATRIX = 1, - SVG_TRANSFORM_TRANSLATE = 2, - SVG_TRANSFORM_SCALE = 3, - SVG_TRANSFORM_ROTATE = 4, - SVG_TRANSFORM_SKEWX = 5, - SVG_TRANSFORM_SKEWY = 6 - }; - - SVGTransform(); - SVGTransform(SVGTransformType); - explicit SVGTransform(const AffineTransform&); - SVGTransformType type() const; +class FloatSize; - AffineTransform matrix() const; - - float angle() const; - FloatPoint rotationCenter() const; - - void setMatrix(AffineTransform); - - void setTranslate(float tx, float ty); - void setScale(float sx, float sy); - void setRotate(float angle, float cx, float cy); - void setSkewX(float angle); - void setSkewY(float angle); - - // Internal use only (animation system) - FloatPoint translate() const; - FloatSize scale() const; - - bool isValid(); - - private: - SVGTransformType m_type; - float m_angle; - FloatPoint m_center; - AffineTransform m_matrix; +class SVGTransform { +public: + enum SVGTransformType { + SVG_TRANSFORM_UNKNOWN = 0, + SVG_TRANSFORM_MATRIX = 1, + SVG_TRANSFORM_TRANSLATE = 2, + SVG_TRANSFORM_SCALE = 3, + SVG_TRANSFORM_ROTATE = 4, + SVG_TRANSFORM_SKEWX = 5, + SVG_TRANSFORM_SKEWY = 6 }; + + SVGTransform(); + SVGTransform(SVGTransformType); + explicit SVGTransform(const AffineTransform&); - inline bool operator==(const SVGTransform& a, const SVGTransform& b) - { - return a.type() == b.type() && a.angle() == b.angle() && a.matrix() == b.matrix(); - } - - inline bool operator!=(const SVGTransform& a, const SVGTransform& b) - { - return !(a == b); - } + SVGTransformType type() const { return m_type; } + + SVGMatrix& svgMatrix() { return static_cast<SVGMatrix&>(m_matrix); } + AffineTransform matrix() const { return m_matrix; } + void updateMatrix(); + + float angle() const { return m_angle; } + FloatPoint rotationCenter() const { return m_center; } + + void setMatrix(const AffineTransform&); + void setTranslate(float tx, float ty); + void setScale(float sx, float sy); + void setRotate(float angle, float cx, float cy); + void setSkewX(float angle); + void setSkewY(float angle); + // Internal use only (animation system) + FloatPoint translate() const; + FloatSize scale() const; + + bool isValid() const { return m_type != SVG_TRANSFORM_UNKNOWN; } + +private: + friend bool operator==(const SVGTransform& a, const SVGTransform& b); + + SVGTransformType m_type; + float m_angle; + FloatPoint m_center; + AffineTransform m_matrix; +}; + +inline bool operator==(const SVGTransform& a, const SVGTransform& b) +{ + return a.m_type == b.m_type && a.m_angle == b.m_angle && a.m_matrix == b.m_matrix; +} + +inline bool operator!=(const SVGTransform& a, const SVGTransform& b) +{ + return !(a == b); +} + } // namespace WebCore #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGTransform.idl b/WebCore/svg/SVGTransform.idl index dde234c..773ad6c 100644 --- a/WebCore/svg/SVGTransform.idl +++ b/WebCore/svg/SVGTransform.idl @@ -21,26 +21,26 @@ module svg { - interface [Conditional=SVG, PODType=SVGTransform] SVGTransform { + interface [Conditional=SVG] SVGTransform { // Transform Types - const unsigned short SVG_TRANSFORM_UNKNOWN = 0; - const unsigned short SVG_TRANSFORM_MATRIX = 1; + const unsigned short SVG_TRANSFORM_UNKNOWN = 0; + const unsigned short SVG_TRANSFORM_MATRIX = 1; const unsigned short SVG_TRANSFORM_TRANSLATE = 2; - const unsigned short SVG_TRANSFORM_SCALE = 3; - const unsigned short SVG_TRANSFORM_ROTATE = 4; - const unsigned short SVG_TRANSFORM_SKEWX = 5; - const unsigned short SVG_TRANSFORM_SKEWY = 6; + const unsigned short SVG_TRANSFORM_SCALE = 3; + const unsigned short SVG_TRANSFORM_ROTATE = 4; + const unsigned short SVG_TRANSFORM_SKEWX = 5; + const unsigned short SVG_TRANSFORM_SKEWY = 6; readonly attribute unsigned short type; readonly attribute SVGMatrix matrix; readonly attribute float angle; - void setMatrix(in SVGMatrix matrix); - void setTranslate(in float tx, in float ty); - void setScale(in float sx, in float sy); - void setRotate(in float angle, in float cx, in float cy); - void setSkewX(in float angle); - void setSkewY(in float angle); + [StrictTypeChecking, RequiresAllArguments=Raise] void setMatrix(in SVGMatrix matrix); + [StrictTypeChecking, RequiresAllArguments=Raise] void setTranslate(in float tx, in float ty); + [StrictTypeChecking, RequiresAllArguments=Raise] void setScale(in float sx, in float sy); + [StrictTypeChecking, RequiresAllArguments=Raise] void setRotate(in float angle, in float cx, in float cy); + [StrictTypeChecking, RequiresAllArguments=Raise] void setSkewX(in float angle); + [StrictTypeChecking, RequiresAllArguments=Raise] void setSkewY(in float angle); }; } diff --git a/WebCore/svg/SVGTransformList.cpp b/WebCore/svg/SVGTransformList.cpp index ae2f298..9137a89 100644 --- a/WebCore/svg/SVGTransformList.cpp +++ b/WebCore/svg/SVGTransformList.cpp @@ -26,53 +26,52 @@ #include "AffineTransform.h" #include "SVGSVGElement.h" #include "SVGTransform.h" +#include <wtf/text/StringConcatenate.h> +#include <wtf/text/StringBuilder.h> -using namespace WebCore; +namespace WebCore { -SVGTransformList::SVGTransformList(const QualifiedName& attributeName) - : SVGPODList<SVGTransform>(attributeName) -{ -} - -SVGTransformList::~SVGTransformList() -{ -} - -SVGTransform SVGTransformList::createSVGTransformFromMatrix(const AffineTransform& matrix) const +SVGTransform SVGTransformList::createSVGTransformFromMatrix(const SVGMatrix& matrix) const { return SVGSVGElement::createSVGTransformFromMatrix(matrix); } SVGTransform SVGTransformList::consolidate() { - ExceptionCode ec = 0; - return initialize(concatenate(), ec); + AffineTransform matrix; + if (!concatenate(matrix)) + return SVGTransform(); + + SVGTransform transform(matrix); + clear(); + append(transform); + return transform; } -SVGTransform SVGTransformList::concatenate() const +bool SVGTransformList::concatenate(AffineTransform& result) const { - unsigned int length = numberOfItems(); - if (!length) - return SVGTransform(); - - AffineTransform matrix; - ExceptionCode ec = 0; - for (unsigned int i = 0; i < length; i++) - matrix = getItem(i, ec).matrix() * matrix; + unsigned size = this->size(); + if (!size) + return false; - return SVGTransform(matrix); + for (unsigned i = 0; i < size; ++i) + result = at(i).matrix() * result; + + return true; } String SVGTransformList::valueAsString() const { // TODO: We may want to build a real transform string, instead of concatting to a matrix(...). - SVGTransform transform = concatenate(); - if (transform.type() == SVGTransform::SVG_TRANSFORM_MATRIX) { - AffineTransform matrix = transform.matrix(); - return String::format("matrix(%f %f %f %f %f %f)", matrix.a(), matrix.b(), matrix.c(), matrix.d(), matrix.e(), matrix.f()); - } + AffineTransform matrix; + concatenate(matrix); - return String(); + StringBuilder builder; + builder.append(makeString("matrix(", String::number(matrix.a()), ' ', String::number(matrix.b()), ' ', String::number(matrix.c()), ' ')); + builder.append(makeString(String::number(matrix.d()), ' ', String::number(matrix.e()), ' ', String::number(matrix.f()), ')')); + return builder.toString(); } +} // namespace WebCore + #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGTransformList.h b/WebCore/svg/SVGTransformList.h index 5bb5e85..e071355 100644 --- a/WebCore/svg/SVGTransformList.h +++ b/WebCore/svg/SVGTransformList.h @@ -22,29 +22,24 @@ #define SVGTransformList_h #if ENABLE(SVG) -#include "SVGList.h" #include "SVGTransform.h" -#include <wtf/Forward.h> -#include <wtf/PassRefPtr.h> +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> namespace WebCore { - class SVGTransformList : public SVGPODList<SVGTransform> { - public: - static PassRefPtr<SVGTransformList> create(const QualifiedName& attributeName) { return adoptRef(new SVGTransformList(attributeName)); } - virtual ~SVGTransformList(); +class SVGTransformList : public Vector<SVGTransform> { +public: + SVGTransformList() { } - SVGTransform createSVGTransformFromMatrix(const AffineTransform&) const; - SVGTransform consolidate(); + SVGTransform createSVGTransformFromMatrix(const SVGMatrix&) const; + SVGTransform consolidate(); - // Internal use only - SVGTransform concatenate() const; + // Internal use only + bool concatenate(AffineTransform& result) const; - String valueAsString() const; - - private: - SVGTransformList(const QualifiedName&); - }; + String valueAsString() const; +}; } // namespace WebCore diff --git a/WebCore/svg/SVGTransformList.idl b/WebCore/svg/SVGTransformList.idl index 08252c3..cdd813d 100644 --- a/WebCore/svg/SVGTransformList.idl +++ b/WebCore/svg/SVGTransformList.idl @@ -31,20 +31,22 @@ module svg { void clear() raises(DOMException); - SVGTransform initialize(in SVGTransform item) + [StrictTypeChecking, RequiresAllArguments=Raise] SVGTransform initialize(in SVGTransform item) raises(DOMException, SVGException); - SVGTransform getItem(in unsigned long index) + [StrictTypeChecking, RequiresAllArguments=Raise] SVGTransform getItem(in unsigned long index) raises(DOMException); - SVGTransform insertItemBefore(in SVGTransform item, in unsigned long index) + [StrictTypeChecking, RequiresAllArguments=Raise] SVGTransform insertItemBefore(in SVGTransform item, in unsigned long index) raises(DOMException, SVGException); - SVGTransform replaceItem(in SVGTransform item, in unsigned long index) + [StrictTypeChecking, RequiresAllArguments=Raise] SVGTransform replaceItem(in SVGTransform item, in unsigned long index) raises(DOMException, SVGException); - SVGTransform removeItem(in unsigned long index) + [StrictTypeChecking, RequiresAllArguments=Raise] SVGTransform removeItem(in unsigned long index) raises(DOMException); - SVGTransform appendItem(in SVGTransform item) + [StrictTypeChecking, RequiresAllArguments=Raise] SVGTransform appendItem(in SVGTransform item) raises(DOMException, SVGException); - SVGTransform createSVGTransformFromMatrix(in SVGMatrix matrix); - SVGTransform consolidate(); + + [StrictTypeChecking, RequiresAllArguments=Raise] SVGTransform createSVGTransformFromMatrix(in SVGMatrix matrix); + SVGTransform consolidate() + raises(DOMException); }; } diff --git a/WebCore/svg/SVGTransformable.cpp b/WebCore/svg/SVGTransformable.cpp index a25e086..006bb94 100644 --- a/WebCore/svg/SVGTransformable.cpp +++ b/WebCore/svg/SVGTransformable.cpp @@ -89,7 +89,7 @@ static int parseTransformParamList(const UChar*& ptr, const UChar* end, float* v static const int requiredValuesForType[] = {0, 6, 1, 1, 1, 1, 1}; static const int optionalValuesForType[] = {0, 0, 1, 1, 2, 0, 0}; -bool SVGTransformable::parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform& t) +bool SVGTransformable::parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform& transform) { if (type == SVGTransform::SVG_TRANSFORM_UNKNOWN) return false; @@ -100,33 +100,33 @@ bool SVGTransformable::parseTransformValue(unsigned type, const UChar*& ptr, con return false; switch (type) { - case SVGTransform::SVG_TRANSFORM_SKEWX: - t.setSkewX(values[0]); - break; - case SVGTransform::SVG_TRANSFORM_SKEWY: - t.setSkewY(values[0]); - break; - case SVGTransform::SVG_TRANSFORM_SCALE: - if (valueCount == 1) // Spec: if only one param given, assume uniform scaling - t.setScale(values[0], values[0]); - else - t.setScale(values[0], values[1]); - break; - case SVGTransform::SVG_TRANSFORM_TRANSLATE: - if (valueCount == 1) // Spec: if only one param given, assume 2nd param to be 0 - t.setTranslate(values[0], 0); - else - t.setTranslate(values[0], values[1]); - break; - case SVGTransform::SVG_TRANSFORM_ROTATE: - if (valueCount == 1) - t.setRotate(values[0], 0, 0); - else - t.setRotate(values[0], values[1], values[2]); - break; - case SVGTransform::SVG_TRANSFORM_MATRIX: - t.setMatrix(AffineTransform(values[0], values[1], values[2], values[3], values[4], values[5])); - break; + case SVGTransform::SVG_TRANSFORM_SKEWX: + transform.setSkewX(values[0]); + break; + case SVGTransform::SVG_TRANSFORM_SKEWY: + transform.setSkewY(values[0]); + break; + case SVGTransform::SVG_TRANSFORM_SCALE: + if (valueCount == 1) // Spec: if only one param given, assume uniform scaling + transform.setScale(values[0], values[0]); + else + transform.setScale(values[0], values[1]); + break; + case SVGTransform::SVG_TRANSFORM_TRANSLATE: + if (valueCount == 1) // Spec: if only one param given, assume 2nd param to be 0 + transform.setTranslate(values[0], 0); + else + transform.setTranslate(values[0], values[1]); + break; + case SVGTransform::SVG_TRANSFORM_ROTATE: + if (valueCount == 1) + transform.setRotate(values[0], 0, 0); + else + transform.setRotate(values[0], values[1], values[2]); + break; + case SVGTransform::SVG_TRANSFORM_MATRIX: + transform.setMatrix(AffineTransform(values[0], values[1], values[2], values[3], values[4], values[5])); + break; } return true; @@ -165,19 +165,16 @@ static inline bool parseAndSkipType(const UChar*& currTransform, const UChar* en return true; } -bool SVGTransformable::parseTransformAttribute(SVGTransformList* list, const AtomicString& transform) +bool SVGTransformable::parseTransformAttribute(SVGTransformList& list, const AtomicString& transform) { const UChar* start = transform.characters(); return parseTransformAttribute(list, start, start + transform.length()); } -bool SVGTransformable::parseTransformAttribute(SVGTransformList* list, const UChar*& currTransform, const UChar* end, TransformParsingMode mode) +bool SVGTransformable::parseTransformAttribute(SVGTransformList& list, const UChar*& currTransform, const UChar* end, TransformParsingMode mode) { - ExceptionCode ec = 0; - if (mode == ClearList) { - list->clear(ec); - ASSERT(!ec); - } + if (mode == ClearList) + list.clear(); bool delimParsed = false; while (currTransform < end) { @@ -188,11 +185,11 @@ bool SVGTransformable::parseTransformAttribute(SVGTransformList* list, const UCh if (!parseAndSkipType(currTransform, end, type)) return false; - SVGTransform t; - if (!parseTransformValue(type, currTransform, end, t)) + SVGTransform transform; + if (!parseTransformValue(type, currTransform, end, transform)) return false; - list->appendItem(t, ec); + list.append(transform); skipOptionalSpaces(currTransform, end); if (currTransform < end && *currTransform == ',') { delimParsed = true; diff --git a/WebCore/svg/SVGTransformable.h b/WebCore/svg/SVGTransformable.h index e2fec4e..1cd2881 100644 --- a/WebCore/svg/SVGTransformable.h +++ b/WebCore/svg/SVGTransformable.h @@ -40,8 +40,8 @@ public: DoNotClearList }; - static bool parseTransformAttribute(SVGTransformList*, const AtomicString& transform); - static bool parseTransformAttribute(SVGTransformList*, const UChar*& ptr, const UChar* end, TransformParsingMode mode = ClearList); + static bool parseTransformAttribute(SVGTransformList&, const AtomicString& transform); + static bool parseTransformAttribute(SVGTransformList&, const UChar*& ptr, const UChar* end, TransformParsingMode mode = ClearList); static bool parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform&); virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const { return animatedLocalTransform(); } diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp index 75ed4c5..a69334c 100644 --- a/WebCore/svg/SVGUseElement.cpp +++ b/WebCore/svg/SVGUseElement.cpp @@ -143,6 +143,9 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) if (isXYAttribute || isWidthHeightAttribute) updateRelativeLengthsInformation(); + if (SVGTests::handleAttributeChange(this, attrName)) + return; + RenderObject* object = renderer(); if (!object) return; @@ -180,8 +183,7 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) return; } - if (SVGTests::isKnownAttribute(attrName) - || SVGLangSpace::isKnownAttribute(attrName) + if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) invalidateShadowTree(); } @@ -743,7 +745,7 @@ void SVGUseElement::removeDisallowedElementsFromSubtree(Node* subtree) if (isDisallowedElement(node)) { Node* next = node->traverseNextSibling(subtree); // The subtree is not in document so this won't generate events that could mutate the tree. - node->parent()->removeChild(node, ec); + node->parentNode()->removeChild(node, ec); node = next; } else node = node->traverseNextNode(subtree); diff --git a/WebCore/svg/SVGViewSpec.cpp b/WebCore/svg/SVGViewSpec.cpp index 2eafff1..d6bade3 100644 --- a/WebCore/svg/SVGViewSpec.cpp +++ b/WebCore/svg/SVGViewSpec.cpp @@ -33,13 +33,12 @@ namespace WebCore { SVGViewSpec::SVGViewSpec(SVGElement* contextElement) : m_contextElement(contextElement) - , m_transform(SVGTransformList::create(SVGNames::transformAttr)) { } void SVGViewSpec::setTransform(const String& transform) { - SVGTransformable::parseTransformAttribute(m_transform.get(), transform); + SVGTransformable::parseTransformAttribute(m_transform, transform); } void SVGViewSpec::setViewBoxString(const String& viewBoxStr) @@ -144,7 +143,7 @@ bool SVGViewSpec::parseViewSpec(const String& viewSpec) if (currViewSpec >= end || *currViewSpec != '(') return false; currViewSpec++; - SVGTransformable::parseTransformAttribute(m_transform.get(), currViewSpec, end, SVGTransformable::DoNotClearList); + SVGTransformable::parseTransformAttribute(m_transform, currViewSpec, end, SVGTransformable::DoNotClearList); if (currViewSpec >= end || *currViewSpec != ')') return false; currViewSpec++; diff --git a/WebCore/svg/SVGViewSpec.h b/WebCore/svg/SVGViewSpec.h index f557d23..dd466ef 100644 --- a/WebCore/svg/SVGViewSpec.h +++ b/WebCore/svg/SVGViewSpec.h @@ -42,7 +42,7 @@ namespace WebCore { bool parseViewSpec(const String&); void setTransform(const String&); - SVGTransformList* transform() const { return m_transform.get(); } + SVGTransformList transform() const { return m_transform; } void setViewBoxString(const String&); @@ -61,7 +61,7 @@ namespace WebCore { DECLARE_ANIMATED_PROPERTY_NEW(SVGViewSpec, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) DECLARE_ANIMATED_PROPERTY_NEW(SVGViewSpec, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) - mutable RefPtr<SVGTransformList> m_transform; + SVGTransformList m_transform; String m_viewTargetString; }; diff --git a/WebCore/svg/animation/SMILTimeContainer.cpp b/WebCore/svg/animation/SMILTimeContainer.cpp index b9f210e..b790859 100644 --- a/WebCore/svg/animation/SMILTimeContainer.cpp +++ b/WebCore/svg/animation/SMILTimeContainer.cpp @@ -255,7 +255,7 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed) sortByPriority(toAnimate, elapsed); // Calculate animation contributions. - typedef HashMap<ElementAttributePair, SVGSMILElement*> ResultElementMap; + typedef HashMap<ElementAttributePair, RefPtr<SVGSMILElement> > ResultElementMap; ResultElementMap resultsElements; for (unsigned n = 0; n < toAnimate.size(); ++n) { SVGSMILElement* animation = toAnimate[n]; @@ -274,7 +274,7 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed) // Results are accumulated to the first animation that animates a particular element/attribute pair. ElementAttributePair key(targetElement, attributeName); - SVGSMILElement* resultElement = resultsElements.get(key); + SVGSMILElement* resultElement = resultsElements.get(key).get(); if (!resultElement) { resultElement = animation; resultElement->resetToBaseValue(baseValueFor(key)); @@ -297,7 +297,7 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed) Vector<SVGSMILElement*> animationsToApply; ResultElementMap::iterator end = resultsElements.end(); for (ResultElementMap::iterator it = resultsElements.begin(); it != end; ++it) - animationsToApply.append(it->second); + animationsToApply.append(it->second.get()); // Sort <animateTranform> to be the last one to be applied. <animate> may change transform attribute as // well (directly or indirectly by modifying <use> x/y) and this way transforms combine properly. diff --git a/WebCore/svg/animation/SVGSMILElement.cpp b/WebCore/svg/animation/SVGSMILElement.cpp index 6757fee..441cfc3 100644 --- a/WebCore/svg/animation/SVGSMILElement.cpp +++ b/WebCore/svg/animation/SVGSMILElement.cpp @@ -147,7 +147,7 @@ void SVGSMILElement::insertedIntoDocument() SVGElement::insertedIntoDocument(); #ifndef NDEBUG // Verify we are not in <use> instance tree. - for (Node* n = this; n; n = n->parent()) + for (ContainerNode* n = this; n; n = n->parentNode()) ASSERT(!n->isShadowNode()); #endif SVGSVGElement* owner = ownerSVGElement(); diff --git a/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h b/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h index 0777b6a..40d3888 100644 --- a/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h +++ b/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h @@ -91,6 +91,7 @@ private: return adoptRef(new SVGAnimatedListPropertyTearOff<PropertyType>(contextElement, attributeName, values)); } +protected: SVGAnimatedListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, PropertyType& values) : SVGAnimatedProperty(contextElement, attributeName) , m_values(values) @@ -99,7 +100,6 @@ private: m_wrappers.fill(0, values.size()); } -private: PropertyType& m_values; // FIXME: The list wrapper cache is shared between baseVal/animVal. If we implement animVal, diff --git a/WebCore/svg/properties/SVGAnimatedPropertyMacros.h b/WebCore/svg/properties/SVGAnimatedPropertyMacros.h index e1c75b9..870d26e 100644 --- a/WebCore/svg/properties/SVGAnimatedPropertyMacros.h +++ b/WebCore/svg/properties/SVGAnimatedPropertyMacros.h @@ -27,6 +27,7 @@ #include "SVGAnimatedStaticPropertyTearOff.h" #include "SVGAnimatedPropertySynchronizer.h" #include "SVGAnimatedPropertyTearOff.h" +#include "SVGAnimatedTransformListPropertyTearOff.h" #include "SVGNames.h" // FIXME: Temporary hack, until we expand the macros in all files, so we don't need a global SVGNames.h include #include "SVGPropertyTraits.h" @@ -156,6 +157,19 @@ void detachAnimated##UpperProperty##ListWrappers(unsigned newListSize) \ static_cast<SVGAnimatedListPropertyTearOff<PropertyType>*>(wrapper)->detachListWrappers(newListSize); \ } +#define DECLARE_ANIMATED_TRANSFORM_LIST_PROPERTY_NEW(OwnerType, DOMAttribute, PropertyType, UpperProperty, LowerProperty) \ +DECLARE_ANIMATED_PROPERTY_NEW_SHARED(OwnerType, DOMAttribute, DOMAttribute.localName(), SVGAnimatedTransformListPropertyTearOff, PropertyType, UpperProperty, LowerProperty) \ +\ +void detachAnimated##UpperProperty##ListWrappers(unsigned newListSize) \ +{ \ + SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \ + SVGAnimatedProperty* wrapper = SVGAnimatedProperty::lookupWrapper<SVGAnimatedTransformListPropertyTearOff>(contextElement, DOMAttribute.localName()); \ + if (!wrapper) \ + return; \ + static_cast<SVGAnimatedTransformListPropertyTearOff*>(wrapper)->detachListWrappers(newListSize); \ +} + + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/properties/SVGAnimatedTransformListPropertyTearOff.h b/WebCore/svg/properties/SVGAnimatedTransformListPropertyTearOff.h new file mode 100644 index 0000000..2aa94c3 --- /dev/null +++ b/WebCore/svg/properties/SVGAnimatedTransformListPropertyTearOff.h @@ -0,0 +1,64 @@ +/* + * 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 SVGAnimatedTransformListPropertyTearOff_h +#define SVGAnimatedTransformListPropertyTearOff_h + +#if ENABLE(SVG) +#include "SVGAnimatedListPropertyTearOff.h" +#include "SVGTransformList.h" +#include "SVGTransformListPropertyTearOff.h" + +namespace WebCore { + +class SVGAnimatedTransformListPropertyTearOff : public SVGAnimatedListPropertyTearOff<SVGTransformList> { +public: + SVGProperty* baseVal() + { + if (!m_baseVal) + m_baseVal = SVGTransformListPropertyTearOff::create(this, BaseValRole); + return m_baseVal.get(); + } + + SVGProperty* animVal() + { + if (!m_animVal) + m_animVal = SVGTransformListPropertyTearOff::create(this, AnimValRole); + return m_animVal.get(); + } + +private: + friend class SVGAnimatedProperty; + + static PassRefPtr<SVGAnimatedTransformListPropertyTearOff> create(SVGElement* contextElement, const QualifiedName& attributeName, SVGTransformList& values) + { + ASSERT(contextElement); + return adoptRef(new SVGAnimatedTransformListPropertyTearOff(contextElement, attributeName, values)); + } + + SVGAnimatedTransformListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, SVGTransformList& values) + : SVGAnimatedListPropertyTearOff<SVGTransformList>(contextElement, attributeName, values) + { + } +}; + +} + +#endif // ENABLE(SVG) +#endif // SVGAnimatedTransformListPropertyTearOff_h diff --git a/WebCore/svg/properties/SVGListProperty.h b/WebCore/svg/properties/SVGListProperty.h index 7edc0f1..f143389 100644 --- a/WebCore/svg/properties/SVGListProperty.h +++ b/WebCore/svg/properties/SVGListProperty.h @@ -287,7 +287,7 @@ public: processIncomingListItemWrapper(newItem, &index); // Detach the existing wrapper. - RefPtr<ListItemTearOff>& oldItem = wrappers.at(index); + RefPtr<ListItemTearOff> oldItem = wrappers.at(index); if (oldItem) oldItem->detachWrapper(); @@ -336,7 +336,7 @@ public: ASSERT(values.size() == wrappers.size()); // Detach the existing wrapper. - RefPtr<ListItemTearOff>& oldItem = wrappers.at(index); + RefPtr<ListItemTearOff> oldItem = wrappers.at(index); if (oldItem) oldItem->detachWrapper(); diff --git a/WebCore/svg/properties/SVGListPropertyTearOff.h b/WebCore/svg/properties/SVGListPropertyTearOff.h index 56d626f..5a71735 100644 --- a/WebCore/svg/properties/SVGListPropertyTearOff.h +++ b/WebCore/svg/properties/SVGListPropertyTearOff.h @@ -109,7 +109,7 @@ public: return Base::appendItemValuesAndWrappers(m_animatedProperty.get(), passNewItem, ec); } -private: +protected: SVGListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role) : SVGListProperty<PropertyType>(role) , m_animatedProperty(animatedProperty) @@ -179,7 +179,6 @@ private: } } -private: // Back pointer to the animated property that created us // For example (text.x.baseVal): m_animatedProperty points to the 'x' SVGAnimatedLengthList object RefPtr<AnimatedListPropertyTearOff> m_animatedProperty; diff --git a/WebCore/svg/properties/SVGProperty.h b/WebCore/svg/properties/SVGProperty.h index 43167b7..104fb0e 100644 --- a/WebCore/svg/properties/SVGProperty.h +++ b/WebCore/svg/properties/SVGProperty.h @@ -34,6 +34,8 @@ enum SVGPropertyRole { class SVGProperty : public RefCounted<SVGProperty> { public: virtual ~SVGProperty() { } + + virtual void commitChange() = 0; }; } diff --git a/WebCore/svg/properties/SVGPropertyTearOff.h b/WebCore/svg/properties/SVGPropertyTearOff.h index 2ffaede..219a4a6 100644 --- a/WebCore/svg/properties/SVGPropertyTearOff.h +++ b/WebCore/svg/properties/SVGPropertyTearOff.h @@ -69,6 +69,9 @@ public: void detachWrapper() { + if (m_valueIsCopy) + return; + // Switch from a live value, to a non-live value. // For example: <text x="50"/> // var item = text.x.baseVal.getItem(0); @@ -76,7 +79,6 @@ public: // item.value still has to report '50' and it has to be possible to modify 'item' // w/o changing the "new item" (with x=100) in the text element. // Whenever the XML DOM modifies the "x" attribute, all existing wrappers are detached, using this function. - ASSERT(!m_valueIsCopy); m_value = new PropertyType(*m_value); m_valueIsCopy = true; m_animatedProperty = 0; diff --git a/WebCore/svg/properties/SVGPropertyTraits.h b/WebCore/svg/properties/SVGPropertyTraits.h index 85bca7e..5364853 100644 --- a/WebCore/svg/properties/SVGPropertyTraits.h +++ b/WebCore/svg/properties/SVGPropertyTraits.h @@ -30,6 +30,7 @@ #include "SVGPointList.h" #include "SVGPreserveAspectRatio.h" #include "SVGStringList.h" +#include "SVGTransformList.h" #include <wtf/text/StringBuilder.h> namespace WebCore { @@ -130,6 +131,13 @@ struct SVGPropertyTraits<SVGPointList> { typedef FloatPoint ListItemType; }; +template<> +struct SVGPropertyTraits<SVGTransformList> { + static SVGTransformList initialValue() { return SVGTransformList(); } + static String toString(const SVGTransformList& type) { return type.valueAsString(); } + typedef SVGTransform ListItemType; +}; + } #endif diff --git a/WebCore/svg/properties/SVGStaticPropertyWithParentTearOff.h b/WebCore/svg/properties/SVGStaticPropertyWithParentTearOff.h new file mode 100644 index 0000000..1e58341 --- /dev/null +++ b/WebCore/svg/properties/SVGStaticPropertyWithParentTearOff.h @@ -0,0 +1,72 @@ +/* + * 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 SVGStaticPropertyWithParentTearOff_h +#define SVGStaticPropertyWithParentTearOff_h + +#if ENABLE(SVG) +#include "SVGPropertyTearOff.h" + +namespace WebCore { + +#if COMPILER(MSVC) +// UpdateMethod is 12 bytes. We have to pack to a size greater than or equal to that to avoid an +// alignment warning (C4121). 16 is the next-largest size allowed for packing, so we use that. +#pragma pack(push, 16) +#endif +template<typename ParentType, typename PropertyType> +class SVGStaticPropertyWithParentTearOff : public SVGPropertyTearOff<PropertyType> { +public: + typedef SVGStaticPropertyWithParentTearOff<ParentType, PropertyType> Self; + typedef void (ParentType::*UpdateMethod)(); + + // Used for non-animated POD types that are not associated with a SVGAnimatedProperty object, nor with a XML DOM attribute + // and that contain a parent type that's exposed to the bindings via a SVGStaticPropertyTearOff object + // (for example: SVGTransform::matrix). + static PassRefPtr<Self> create(SVGProperty* parent, PropertyType& value, UpdateMethod update) + { + ASSERT(parent); + return adoptRef(new Self(parent, value, update)); + } + + virtual void commitChange() + { + (static_cast<SVGPropertyTearOff<ParentType>*>(m_parent.get())->propertyReference().*m_update)(); + m_parent->commitChange(); + } + +private: + SVGStaticPropertyWithParentTearOff(SVGProperty* parent, PropertyType& value, UpdateMethod update) + : SVGPropertyTearOff<PropertyType>(0, value) + , m_update(update) + , m_parent(parent) + { + } + + UpdateMethod m_update; + RefPtr<SVGProperty> m_parent; +}; +#if COMPILER(MSVC) +#pragma pack(pop) +#endif + +} + +#endif // ENABLE(SVG) +#endif // SVGStaticPropertyWithParentTearOff_h diff --git a/WebCore/svg/properties/SVGTransformListPropertyTearOff.h b/WebCore/svg/properties/SVGTransformListPropertyTearOff.h new file mode 100644 index 0000000..636871a --- /dev/null +++ b/WebCore/svg/properties/SVGTransformListPropertyTearOff.h @@ -0,0 +1,75 @@ +/* + * 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 SVGTransformListPropertyTearOff_h +#define SVGTransformListPropertyTearOff_h + +#if ENABLE(SVG) +#include "SVGListPropertyTearOff.h" + +namespace WebCore { + +// SVGTransformList contains two additional methods, that can be exposed to the bindings. +class SVGTransformListPropertyTearOff : public SVGListPropertyTearOff<SVGTransformList> { +public: + typedef SVGAnimatedListPropertyTearOff<SVGTransformList> AnimatedListPropertyTearOff; + typedef SVGAnimatedListPropertyTearOff<SVGTransformList>::ListWrapperCache ListWrapperCache; + + static PassRefPtr<SVGListPropertyTearOff<SVGTransformList> > create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role) + { + ASSERT(animatedProperty); + return adoptRef(new SVGTransformListPropertyTearOff(animatedProperty, role)); + } + + PassRefPtr<SVGPropertyTearOff<SVGTransform> > createSVGTransformFromMatrix(SVGPropertyTearOff<SVGMatrix>* matrix) + { + ASSERT(matrix); + SVGTransformList& values = m_animatedProperty->values(); + return SVGPropertyTearOff<SVGTransform>::create(values.createSVGTransformFromMatrix(matrix->propertyReference())); + } + + PassRefPtr<SVGPropertyTearOff<SVGTransform> > consolidate(ExceptionCode& ec) + { + if (!canAlterList(ec)) + return 0; + + SVGTransformList& values = m_animatedProperty->values(); + ListWrapperCache& wrappers = m_animatedProperty->wrappers(); + ASSERT(values.size() == wrappers.size()); + + m_animatedProperty->detachListWrappers(0); + RefPtr<SVGPropertyTearOff<SVGTransform> > wrapper = SVGPropertyTearOff<SVGTransform>::create(values.consolidate()); + wrappers.append(wrapper); + + ASSERT(values.size() == wrappers.size()); + return wrapper.release(); + } + +private: + SVGTransformListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role) + : SVGListPropertyTearOff<SVGTransformList>(animatedProperty, role) + { + } + +}; + +} + +#endif // ENABLE(SVG) +#endif // SVGListPropertyTearOff_h |