diff options
author | Ben Murdoch <benm@google.com> | 2011-05-24 11:24:40 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-06-02 09:53:15 +0100 |
commit | 81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch) | |
tree | 7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebCore/svg | |
parent | 94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff) | |
download | external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2 |
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/WebCore/svg')
72 files changed, 1102 insertions, 573 deletions
diff --git a/Source/WebCore/svg/SVGAnimateElement.cpp b/Source/WebCore/svg/SVGAnimateElement.cpp index 0dfe086..33ca46b 100644 --- a/Source/WebCore/svg/SVGAnimateElement.cpp +++ b/Source/WebCore/svg/SVGAnimateElement.cpp @@ -24,6 +24,8 @@ #if ENABLE(SVG) && ENABLE(SVG_ANIMATION) #include "SVGAnimateElement.h" +#include "CSSComputedStyleDeclaration.h" +#include "CSSParser.h" #include "CSSPropertyNames.h" #include "ColorDistance.h" #include "FloatConversion.h" @@ -35,6 +37,7 @@ #include "SVGPathParserFactory.h" #include "SVGPathSegList.h" #include "SVGPointList.h" +#include "SVGStyledElement.h" using namespace std; @@ -42,7 +45,7 @@ namespace WebCore { SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, Document* document) : SVGAnimationElement(tagName, document) - , m_propertyType(StringProperty) + , m_animatedAttributeType(AnimatedString) , m_fromNumber(0) , m_toNumber(0) , m_animatedNumber(numeric_limits<double>::infinity()) @@ -85,55 +88,125 @@ static bool parseNumberValueAndUnit(const String& in, double& value, String& uni return ok; } -static inline bool adjustForCurrentColor(Color& color, const String& value, SVGElement* target) +static inline void adjustForCurrentColor(SVGElement* targetElement, Color& color) { - if (!target || !target->isStyled() || value != "currentColor") - return false; + ASSERT(targetElement); - if (RenderObject* targetRenderer = target->renderer()) + if (RenderObject* targetRenderer = targetElement->renderer()) color = targetRenderer->style()->visitedDependentColor(CSSPropertyColor); + else + color = Color(); +} - return true; +static inline void adjustForInheritance(SVGElement* targetElement, const QualifiedName& attributeName, String& value) +{ + // FIXME: At the moment the computed style gets returned as a String and needs to get parsed again. + // In the future we might want to work with the value type directly to avoid the String parsing. + ASSERT(targetElement); + + Element* parent = targetElement->parentElement(); + if (!parent || !parent->isSVGElement()) + return; + + SVGElement* svgParent = static_cast<SVGElement*>(parent); + if (svgParent->isStyled()) + value = computedStyle(svgParent)->getPropertyValue(cssPropertyID(attributeName.localName())); +} + +bool SVGAnimateElement::hasValidAttributeType() const +{ + SVGElement* targetElement = this->targetElement(); + if (!targetElement) + return false; + + return determineAnimatedAttributeType(targetElement) != AnimatedUnknown; } -SVGAnimateElement::PropertyType SVGAnimateElement::determinePropertyType(const String& attribute) const +AnimatedAttributeType SVGAnimateElement::determineAnimatedAttributeType(SVGElement* targetElement) const { - // FIXME: We should not allow animation of attribute types other than AnimatedColor for <animateColor>. - if (hasTagName(SVGNames::animateColorTag)) - return ColorProperty; - - // FIXME: Now that we have a full property table we need a more granular type specific animation. - AnimatedAttributeType type = targetElement()->animatedPropertyTypeForAttribute(QualifiedName(nullAtom, attribute, nullAtom)); - if (type == AnimatedColor) - return ColorProperty; - if (type == AnimatedPath) - return PathProperty; - if (type == AnimatedPoints) - return PointsProperty; - return NumberProperty; + ASSERT(targetElement); + + AnimatedAttributeType type = targetElement->animatedPropertyTypeForAttribute(attributeName()); + if (type == AnimatedUnknown || (hasTagName(SVGNames::animateColorTag) && type != AnimatedColor)) + return AnimatedUnknown; + + // FIXME: We need type specific animations in the future. Many animations marked as AnimatedString today will + // support continuous animations. + switch (type) { + case AnimatedBoolean: + case AnimatedEnumeration: + case AnimatedLengthList: + case AnimatedNumberList: + case AnimatedNumberOptionalNumber: + case AnimatedPreserveAspectRatio: + case AnimatedRect: + case AnimatedString: + return AnimatedString; + case AnimatedAngle: + case AnimatedInteger: + case AnimatedLength: + case AnimatedNumber: + return AnimatedNumber; + case AnimatedPath: + return AnimatedPath; + case AnimatedPoints: + return AnimatedPoints; + case AnimatedColor: + return AnimatedColor; + case AnimatedUnknown: + case AnimatedTransformList: + // Animations of transform lists are not allowed for <animate> or <set> + // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties + return AnimatedUnknown; + } + + ASSERT_NOT_REACHED(); + return AnimatedUnknown; } void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement) { - ASSERT(percentage >= 0.f && percentage <= 1.f); + ASSERT(percentage >= 0 && percentage <= 1); ASSERT(resultElement); - bool isInFirstHalfOfAnimation = percentage < 0.5; + bool isInFirstHalfOfAnimation = percentage < 0.5f; AnimationMode animationMode = this->animationMode(); + SVGElement* targetElement = 0; + // Avoid targetElement() call if possible. It might slow down animations. + if (m_fromPropertyValueType == InheritValue || m_toPropertyValueType == InheritValue + || m_fromPropertyValueType == CurrentColorValue || m_toPropertyValueType == CurrentColorValue) { + targetElement = this->targetElement(); + if (!targetElement) + return; + } if (hasTagName(SVGNames::setTag)) - percentage = 1.f; + percentage = 1; if (!resultElement->hasTagName(SVGNames::animateTag) && !resultElement->hasTagName(SVGNames::animateColorTag) && !resultElement->hasTagName(SVGNames::setTag)) return; SVGAnimateElement* results = static_cast<SVGAnimateElement*>(resultElement); // Can't accumulate over a string property. - if (results->m_propertyType == StringProperty && m_propertyType != StringProperty) + if (results->m_animatedAttributeType == AnimatedString && m_animatedAttributeType != AnimatedString) return; - if (m_propertyType == NumberProperty) { + if (m_animatedAttributeType == AnimatedNumber) { // To animation uses contributions from the lower priority animations as the base value. if (animationMode == ToAnimation) m_fromNumber = results->m_animatedNumber; + // Replace 'currentColor' / 'inherit' by their computed property values. + if (m_fromPropertyValueType == InheritValue) { + String fromNumberString; + adjustForInheritance(targetElement, attributeName(), fromNumberString); + if (!parseNumberValueAndUnit(fromNumberString, m_fromNumber, m_numberUnit)) + return; + } + if (m_toPropertyValueType == InheritValue) { + String toNumberString; + adjustForInheritance(targetElement, attributeName(), toNumberString); + if (!parseNumberValueAndUnit(toNumberString, m_toNumber, m_numberUnit)) + return; + } + double number; if (calcMode() == CalcModeDiscrete) number = isInFirstHalfOfAnimation ? m_fromNumber : m_toNumber; @@ -149,9 +222,26 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat results->m_animatedNumber = number; return; } - if (m_propertyType == ColorProperty) { + if (m_animatedAttributeType == AnimatedColor) { if (animationMode == ToAnimation) m_fromColor = results->m_animatedColor; + + // Replace 'currentColor' / 'inherit' by their computed property values. + if (m_fromPropertyValueType == CurrentColorValue) + adjustForCurrentColor(targetElement, m_fromColor); + else if (m_fromPropertyValueType == InheritValue) { + String fromColorString; + adjustForInheritance(targetElement, attributeName(), fromColorString); + m_fromColor = SVGColor::colorFromRGBColorString(fromColorString); + } + if (m_toPropertyValueType == CurrentColorValue) + adjustForCurrentColor(targetElement, m_toColor); + else if (m_toPropertyValueType == InheritValue) { + String toColorString; + adjustForInheritance(targetElement, attributeName(), toColorString); + m_toColor = SVGColor::colorFromRGBColorString(toColorString); + } + Color color; if (calcMode() == CalcModeDiscrete) color = isInFirstHalfOfAnimation ? m_fromColor : m_toColor; @@ -165,7 +255,7 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat results->m_animatedColor = color; return; } - if (m_propertyType == PathProperty) { + if (m_animatedAttributeType == AnimatedPath) { if (animationMode == ToAnimation) { ASSERT(results->m_animatedPathPointer); m_fromPath = results->m_animatedPathPointer->copy(); @@ -174,7 +264,7 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat ASSERT(m_fromPath); ASSERT(percentage >= 0); results->m_animatedPathPointer = m_fromPath.get(); - } else if (percentage == 1.f) { + } else if (percentage == 1) { ASSERT(m_toPath); results->m_animatedPathPointer = m_toPath.get(); } else { @@ -192,16 +282,16 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat ASSERT(m_fromPath); ASSERT(m_toPath); ASSERT(!results->m_animatedPath); - results->m_animatedPathPointer = ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1.0f) + results->m_animatedPathPointer = ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1) ? m_toPath.get() : m_fromPath.get(); } } return; } - if (m_propertyType == PointsProperty) { + if (m_animatedAttributeType == AnimatedPoints) { if (!percentage) results->m_animatedPoints = m_fromPoints; - else if (percentage == 1.f) + else if (percentage == 1) results->m_animatedPoints = m_toPoints; else { if (!m_fromPoints.isEmpty() && !m_toPoints.isEmpty()) @@ -210,40 +300,75 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat results->m_animatedPoints.clear(); // Fall back to discrete animation if the points are not compatible if (results->m_animatedPoints.isEmpty()) - results->m_animatedPoints = ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1.0f) + results->m_animatedPoints = ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1) ? m_toPoints : m_fromPoints; } return; } ASSERT(animationMode == FromToAnimation || animationMode == ToAnimation || animationMode == ValuesAnimation); - if ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1.0f) + // Replace 'currentColor' / 'inherit' by their computed property values. + if (m_fromPropertyValueType == InheritValue) + adjustForInheritance(targetElement, attributeName(), m_fromString); + if (m_toPropertyValueType == InheritValue) + adjustForInheritance(targetElement, attributeName(), m_toString); + + if ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1) results->m_animatedString = m_toString; else results->m_animatedString = m_fromString; // Higher priority replace animation overrides any additive results so far. - results->m_propertyType = StringProperty; + results->m_animatedAttributeType = AnimatedString; +} + +static bool inheritsFromProperty(SVGElement* targetElement, const QualifiedName& attributeName, const String& value) +{ + ASSERT(targetElement); + DEFINE_STATIC_LOCAL(const AtomicString, inherit, ("inherit")); + + if (value.isEmpty() || value != inherit || !targetElement->isStyled()) + return false; + return SVGStyledElement::isAnimatableCSSProperty(attributeName); +} + +static bool attributeValueIsCurrentColor(const String& value) +{ + DEFINE_STATIC_LOCAL(const AtomicString, currentColor, ("currentColor")); + return value == currentColor; } bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const String& toString) { + SVGElement* targetElement = this->targetElement(); + if (!targetElement) + return false; + m_fromPropertyValueType = inheritsFromProperty(targetElement, attributeName(), fromString) ? InheritValue : RegularPropertyValue; + m_toPropertyValueType = inheritsFromProperty(targetElement, attributeName(), toString) ? InheritValue : RegularPropertyValue; + // FIXME: Needs more solid way determine target attribute type. - m_propertyType = determinePropertyType(attributeName()); - if (m_propertyType == ColorProperty) { - SVGElement* targetElement = this->targetElement(); - if (!adjustForCurrentColor(m_fromColor, fromString, targetElement)) + m_animatedAttributeType = determineAnimatedAttributeType(targetElement); + if (m_animatedAttributeType == AnimatedColor) { + bool fromIsCurrentColor = attributeValueIsCurrentColor(fromString); + bool toIsCurrentColor = attributeValueIsCurrentColor(toString); + if (fromIsCurrentColor) + m_fromPropertyValueType = CurrentColorValue; + else m_fromColor = SVGColor::colorFromRGBColorString(fromString); - if (!adjustForCurrentColor(m_toColor, toString, targetElement)) + if (toIsCurrentColor) + m_toPropertyValueType = CurrentColorValue; + else m_toColor = SVGColor::colorFromRGBColorString(toString); - if ((m_fromColor.isValid() && m_toColor.isValid()) || (m_toColor.isValid() && animationMode() == ToAnimation)) + bool fromIsValid = m_fromColor.isValid() || fromIsCurrentColor || m_fromPropertyValueType == InheritValue; + bool toIsValid = m_toColor.isValid() || toIsCurrentColor || m_toPropertyValueType == InheritValue; + if ((fromIsValid && toIsValid) || (toIsValid && animationMode() == ToAnimation)) return true; - } else if (m_propertyType == NumberProperty) { + } else if (m_animatedAttributeType == AnimatedNumber) { m_numberUnit = String(); if (parseNumberValueAndUnit(toString, m_toNumber, m_numberUnit)) { // For to-animations the from number is calculated later if (animationMode() == ToAnimation || parseNumberValueAndUnit(fromString, m_fromNumber, m_numberUnit)) return true; } - } else if (m_propertyType == PathProperty) { + } else if (m_animatedAttributeType == AnimatedPath) { SVGPathParserFactory* factory = SVGPathParserFactory::self(); if (factory->buildSVGPathByteStreamFromString(toString, m_toPath, UnalteredParsing)) { // For to-animations the from number is calculated later @@ -252,7 +377,7 @@ bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const } m_fromPath.clear(); m_toPath.clear(); - } else if (m_propertyType == PointsProperty) { + } else if (m_animatedAttributeType == AnimatedPoints) { m_fromPoints.clear(); if (pointsListFromSVGData(m_fromPoints, fromString)) { m_toPoints.clear(); @@ -262,22 +387,34 @@ bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const } m_fromString = fromString; m_toString = toString; - m_propertyType = StringProperty; + m_animatedAttributeType = AnimatedString; return true; } bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, const String& byString) { + SVGElement* targetElement = this->targetElement(); + if (!targetElement) + return false; + m_fromPropertyValueType = inheritsFromProperty(targetElement, attributeName(), fromString) ? InheritValue : RegularPropertyValue; + m_toPropertyValueType = inheritsFromProperty(targetElement, attributeName(), byString) ? InheritValue : RegularPropertyValue; + ASSERT(!hasTagName(SVGNames::setTag)); - m_propertyType = determinePropertyType(attributeName()); - if (m_propertyType == ColorProperty) { - SVGElement* targetElement = this->targetElement(); - if (!adjustForCurrentColor(m_fromColor, fromString, targetElement)) - m_fromColor = fromString.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(fromString); - if (!adjustForCurrentColor(m_toColor, byString, targetElement)) + m_animatedAttributeType = determineAnimatedAttributeType(targetElement); + if (m_animatedAttributeType == AnimatedColor) { + bool fromIsCurrentColor = attributeValueIsCurrentColor(fromString); + bool byIsCurrentColor = attributeValueIsCurrentColor(byString); + if (fromIsCurrentColor) + m_fromPropertyValueType = CurrentColorValue; + else + m_fromColor = SVGColor::colorFromRGBColorString(fromString); + if (byIsCurrentColor) + m_toPropertyValueType = CurrentColorValue; + else m_toColor = SVGColor::colorFromRGBColorString(byString); - m_toColor = ColorDistance::addColorsAndClamp(m_fromColor, m_toColor); - if (!m_fromColor.isValid() || !m_toColor.isValid()) + + if ((!m_fromColor.isValid() && !fromIsCurrentColor) + || (!m_toColor.isValid() && !byIsCurrentColor)) return false; } else { m_numberUnit = String(); @@ -293,16 +430,18 @@ bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, const void SVGAnimateElement::resetToBaseValue(const String& baseString) { + SVGElement* targetElement = this->targetElement(); + ASSERT(targetElement); m_animatedString = baseString; - PropertyType lastType = m_propertyType; - m_propertyType = determinePropertyType(attributeName()); - if (m_propertyType == ColorProperty) { + AnimatedAttributeType lastType = m_animatedAttributeType; + m_animatedAttributeType = determineAnimatedAttributeType(targetElement); + if (m_animatedAttributeType == AnimatedColor) { m_animatedColor = baseString.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(baseString); if (isContributing(elapsed())) { - m_propertyType = lastType; + m_animatedAttributeType = lastType; return; } - } else if (m_propertyType == NumberProperty) { + } else if (m_animatedAttributeType == AnimatedNumber) { if (baseString.isEmpty()) { m_animatedNumber = 0; m_numberUnit = String(); @@ -310,27 +449,27 @@ void SVGAnimateElement::resetToBaseValue(const String& baseString) } if (parseNumberValueAndUnit(baseString, m_animatedNumber, m_numberUnit)) return; - } else if (m_propertyType == PathProperty) { + } else if (m_animatedAttributeType == AnimatedPath) { m_animatedPath.clear(); SVGPathParserFactory* factory = SVGPathParserFactory::self(); factory->buildSVGPathByteStreamFromString(baseString, m_animatedPath, UnalteredParsing); m_animatedPathPointer = m_animatedPath.get(); return; - } else if (m_propertyType == PointsProperty) { + } else if (m_animatedAttributeType == AnimatedPoints) { m_animatedPoints.clear(); return; } - m_propertyType = StringProperty; + m_animatedAttributeType = AnimatedString; } void SVGAnimateElement::applyResultsToTarget() { String valueToApply; - if (m_propertyType == ColorProperty) - valueToApply = m_animatedColor.name(); - else if (m_propertyType == NumberProperty) + if (m_animatedAttributeType == AnimatedColor) + valueToApply = m_animatedColor.serialized(); + else if (m_animatedAttributeType == AnimatedNumber) valueToApply = String::number(m_animatedNumber) + m_numberUnit; - else if (m_propertyType == PathProperty) { + else if (m_animatedAttributeType == AnimatedPath) { if (!m_animatedPathPointer || m_animatedPathPointer->isEmpty()) valueToApply = m_animatedString; else { @@ -341,7 +480,7 @@ void SVGAnimateElement::applyResultsToTarget() SVGPathParserFactory* factory = SVGPathParserFactory::self(); factory->buildStringFromByteStream(m_animatedPathPointer, valueToApply, UnalteredParsing); } - } else if (m_propertyType == PointsProperty) + } else if (m_animatedAttributeType == AnimatedPoints) valueToApply = m_animatedPoints.isEmpty() ? m_animatedString : m_animatedPoints.valueAsString(); else valueToApply = m_animatedString; @@ -351,31 +490,31 @@ void SVGAnimateElement::applyResultsToTarget() float SVGAnimateElement::calculateDistance(const String& fromString, const String& toString) { - m_propertyType = determinePropertyType(attributeName()); - if (m_propertyType == NumberProperty) { + SVGElement* targetElement = this->targetElement(); + if (!targetElement) + return -1; + m_animatedAttributeType = determineAnimatedAttributeType(targetElement); + if (m_animatedAttributeType == AnimatedNumber) { double from; double to; String unit; if (!parseNumberValueAndUnit(fromString, from, unit)) - return -1.f; + return -1; if (!parseNumberValueAndUnit(toString, to, unit)) - return -1.f; + return -1; return narrowPrecisionToFloat(fabs(to - from)); } - if (m_propertyType == ColorProperty) { + if (m_animatedAttributeType == AnimatedColor) { Color from = SVGColor::colorFromRGBColorString(fromString); if (!from.isValid()) - return -1.f; + return -1; Color to = SVGColor::colorFromRGBColorString(toString); if (!to.isValid()) - return -1.f; + return -1; return ColorDistance(from, to).distance(); } - return -1.f; + return -1; } } - -// vim:ts=4:noet #endif // ENABLE(SVG) - diff --git a/Source/WebCore/svg/SVGAnimateElement.h b/Source/WebCore/svg/SVGAnimateElement.h index 3217c4a..75be4b2 100644 --- a/Source/WebCore/svg/SVGAnimateElement.h +++ b/Source/WebCore/svg/SVGAnimateElement.h @@ -51,10 +51,20 @@ protected: virtual float calculateDistance(const String& fromString, const String& toString); private: - enum PropertyType { NumberProperty, ColorProperty, StringProperty, PathProperty, PointsProperty }; - PropertyType determinePropertyType(const String& attribute) const; - PropertyType m_propertyType; + // If we have 'currentColor' or 'inherit' as animation value, we need to grab the value during the animation + // since the value can be animated itself. + enum AnimatedPropertyValueType { + RegularPropertyValue, + CurrentColorValue, + InheritValue + }; + + virtual bool hasValidAttributeType() const; + AnimatedAttributeType determineAnimatedAttributeType(SVGElement*) const; + AnimatedAttributeType m_animatedAttributeType; + AnimatedPropertyValueType m_fromPropertyValueType; + AnimatedPropertyValueType m_toPropertyValueType; double m_fromNumber; double m_toNumber; double m_animatedNumber; diff --git a/Source/WebCore/svg/SVGAnimateMotionElement.cpp b/Source/WebCore/svg/SVGAnimateMotionElement.cpp index ec51548..e0202e4 100644 --- a/Source/WebCore/svg/SVGAnimateMotionElement.cpp +++ b/Source/WebCore/svg/SVGAnimateMotionElement.cpp @@ -53,14 +53,17 @@ PassRefPtr<SVGAnimateMotionElement> SVGAnimateMotionElement::create(const Qualif return adoptRef(new SVGAnimateMotionElement(tagName, document)); } -bool SVGAnimateMotionElement::hasValidTarget() const +bool SVGAnimateMotionElement::hasValidAttributeType() const { - if (!SVGAnimationElement::hasValidTarget()) - return false; SVGElement* targetElement = this->targetElement(); + if (!targetElement) + return false; + + // We don't have a special attribute name to verify the animation type. Check the element name instead. if (!targetElement->isStyledTransformable() && !targetElement->hasTagName(SVGNames::textTag)) return false; // Spec: SVG 1.1 section 19.2.15 + // FIXME: svgTag is missing. Needs to be checked, if transforming <svg> could cause problems. if (targetElement->hasTagName(gTag) || targetElement->hasTagName(defsTag) || targetElement->hasTagName(useTag) @@ -134,11 +137,11 @@ static bool parsePoint(const String& s, FloatPoint& point) if (!skipOptionalSpaces(cur, end)) return false; - float x = 0.0f; + float x = 0; if (!parseNumber(cur, end, x)) return false; - float y = 0.0f; + float y = 0; if (!parseNumber(cur, end, y)) return false; @@ -150,10 +153,9 @@ static bool parsePoint(const String& s, FloatPoint& point) void SVGAnimateMotionElement::resetToBaseValue(const String&) { - if (!hasValidTarget()) + if (!hasValidAttributeType()) return; - SVGElement* target = targetElement(); - AffineTransform* transform = target->supplementalTransform(); + AffineTransform* transform = targetElement()->supplementalTransform(); if (!transform) return; transform->makeIdentity(); @@ -177,15 +179,15 @@ bool SVGAnimateMotionElement::calculateFromAndByValues(const String& fromString, void SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned, SVGSMILElement*) { - SVGElement* target = targetElement(); - if (!target) + SVGElement* targetElement = this->targetElement(); + if (!targetElement) return; - AffineTransform* transform = target->supplementalTransform(); + AffineTransform* transform = targetElement->supplementalTransform(); if (!transform) return; - if (target->renderer()) - target->renderer()->setNeedsTransformUpdate(); + if (RenderObject* targetRenderer = targetElement->renderer()) + targetRenderer->setNeedsTransformUpdate(); if (!isAdditive()) transform->makeIdentity(); @@ -204,7 +206,7 @@ void SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned, if (rotateMode == RotateAuto || rotateMode == RotateAutoReverse) { float angle = path.normalAngleAtLength(positionOnPath, ok); if (rotateMode == RotateAutoReverse) - angle += 180.f; + angle += 180; transform->rotate(angle); } } @@ -250,13 +252,12 @@ float SVGAnimateMotionElement::calculateDistance(const String& fromString, const FloatPoint from; FloatPoint to; if (!parsePoint(fromString, from)) - return -1.f; + return -1; if (!parsePoint(toString, to)) - return -1.f; + return -1; FloatSize diff = to - from; return sqrtf(diff.width() * diff.width() + diff.height() * diff.height()); } } - #endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimateMotionElement.h b/Source/WebCore/svg/SVGAnimateMotionElement.h index 7e168c3..96861b6 100644 --- a/Source/WebCore/svg/SVGAnimateMotionElement.h +++ b/Source/WebCore/svg/SVGAnimateMotionElement.h @@ -34,7 +34,7 @@ public: private: SVGAnimateMotionElement(const QualifiedName&, Document*); - virtual bool hasValidTarget() const; + virtual bool hasValidAttributeType() const; virtual void parseMappedAttribute(Attribute*); @@ -73,5 +73,3 @@ private: #endif // ENABLE(SVG_ANIMATION) #endif // SVGAnimateMotionElement_h - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGAnimateTransformElement.cpp b/Source/WebCore/svg/SVGAnimateTransformElement.cpp index bdcab38..6e1fb99 100644 --- a/Source/WebCore/svg/SVGAnimateTransformElement.cpp +++ b/Source/WebCore/svg/SVGAnimateTransformElement.cpp @@ -59,14 +59,25 @@ PassRefPtr<SVGAnimateTransformElement> SVGAnimateTransformElement::create(const return adoptRef(new SVGAnimateTransformElement(tagName, document)); } -bool SVGAnimateTransformElement::hasValidTarget() const +bool SVGAnimateTransformElement::hasValidAttributeType() const { SVGElement* targetElement = this->targetElement(); - return SVGAnimationElement::hasValidTarget() - && (targetElement->isStyledTransformable() - || targetElement->hasTagName(SVGNames::textTag) - || targetElement->hasTagName(SVGNames::linearGradientTag) - || targetElement->hasTagName(SVGNames::radialGradientTag)); + if (!targetElement) + return false; + + return determineAnimatedAttributeType(targetElement) == AnimatedTransformList; +} + +AnimatedAttributeType SVGAnimateTransformElement::determineAnimatedAttributeType(SVGElement* targetElement) const +{ + ASSERT(targetElement); + + // Just transform lists can be animated with <animateTransform> + // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties + if (targetElement->animatedPropertyTypeForAttribute(attributeName()) != AnimatedTransformList) + return AnimatedUnknown; + + return AnimatedTransformList; } void SVGAnimateTransformElement::parseMappedAttribute(Attribute* attr) @@ -102,26 +113,27 @@ static SVGTransformList* transformListFor(SVGElement* element) void SVGAnimateTransformElement::resetToBaseValue(const String& baseValue) { - if (!hasValidTarget()) + SVGElement* targetElement = this->targetElement(); + if (!targetElement || determineAnimatedAttributeType(targetElement) == AnimatedUnknown) return; - if (targetElement()->hasTagName(SVGNames::linearGradientTag) || targetElement()->hasTagName(SVGNames::radialGradientTag)) { - targetElement()->setAttribute(SVGNames::gradientTransformAttr, baseValue.isEmpty() ? "matrix(1 0 0 1 0 0)" : baseValue); + if (targetElement->hasTagName(SVGNames::linearGradientTag) || targetElement->hasTagName(SVGNames::radialGradientTag)) { + targetElement->setAttribute(SVGNames::gradientTransformAttr, baseValue.isEmpty() ? "matrix(1 0 0 1 0 0)" : baseValue); return; } if (baseValue.isEmpty()) { - if (SVGTransformList* list = transformListFor(targetElement())) + if (SVGTransformList* list = transformListFor(targetElement)) list->clear(); } else - targetElement()->setAttribute(SVGNames::transformAttr, baseValue); + targetElement->setAttribute(SVGNames::transformAttr, baseValue); } -void SVGAnimateTransformElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement) +void SVGAnimateTransformElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement*) { - if (!hasValidTarget()) + SVGElement* targetElement = this->targetElement(); + if (!targetElement || determineAnimatedAttributeType(targetElement) == AnimatedUnknown) return; - SVGElement* targetElement = resultElement->targetElement(); SVGTransformList* transformList = transformListFor(targetElement); ASSERT(transformList); @@ -146,7 +158,6 @@ bool SVGAnimateTransformElement::calculateFromAndToValues(const String& fromStri bool SVGAnimateTransformElement::calculateFromAndByValues(const String& fromString, const String& byString) { - m_fromTransform = parseTransformValue(fromString); if (!m_fromTransform.isValid()) return false; @@ -168,13 +179,11 @@ SVGTransform SVGAnimateTransformElement::parseTransformValue(const String& value void SVGAnimateTransformElement::applyResultsToTarget() { - if (!hasValidTarget()) - return; - // We accumulate to the target element transform list so there is not much to do here. SVGElement* targetElement = this->targetElement(); - if (!targetElement) + if (!targetElement || determineAnimatedAttributeType(targetElement) == AnimatedUnknown) return; + // We accumulate to the target element transform list so there is not much to do here. if (RenderObject* renderer = targetElement->renderer()) { renderer->setNeedsTransformUpdate(); RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); @@ -210,10 +219,10 @@ float SVGAnimateTransformElement::calculateDistance(const String& fromString, co // is paced separately. To implement this we need to treat each component as individual animation everywhere. SVGTransform from = parseTransformValue(fromString); if (!from.isValid()) - return -1.f; + return -1; SVGTransform to = parseTransformValue(toString); if (!to.isValid() || from.type() != to.type()) - return -1.f; + return -1; if (to.type() == SVGTransform::SVG_TRANSFORM_TRANSLATE) { FloatSize diff = to.translate() - from.translate(); return sqrtf(diff.width() * diff.width() + diff.height() * diff.height()); @@ -224,11 +233,8 @@ float SVGAnimateTransformElement::calculateDistance(const String& fromString, co FloatSize diff = to.scale() - from.scale(); return sqrtf(diff.width() * diff.width() + diff.height() * diff.height()); } - return -1.f; + return -1; } } - -// vim:ts=4:noet #endif // ENABLE(SVG) - diff --git a/Source/WebCore/svg/SVGAnimateTransformElement.h b/Source/WebCore/svg/SVGAnimateTransformElement.h index 0f806d7..6ebc97e 100644 --- a/Source/WebCore/svg/SVGAnimateTransformElement.h +++ b/Source/WebCore/svg/SVGAnimateTransformElement.h @@ -39,7 +39,8 @@ public: private: SVGAnimateTransformElement(const QualifiedName&, Document*); - virtual bool hasValidTarget() const; + virtual bool hasValidAttributeType() const; + AnimatedAttributeType determineAnimatedAttributeType(SVGElement*) const; virtual void parseMappedAttribute(Attribute*); @@ -64,5 +65,3 @@ private: #endif // ENABLE(SVG) #endif // SVGAnimateTransformElement_h - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGAnimationElement.cpp b/Source/WebCore/svg/SVGAnimationElement.cpp index c56e3b6..21784c2 100644 --- a/Source/WebCore/svg/SVGAnimationElement.cpp +++ b/Source/WebCore/svg/SVGAnimationElement.cpp @@ -41,6 +41,7 @@ #include "SVGElementInstance.h" #include "SVGNames.h" #include "SVGParserUtilities.h" +#include "SVGStyledElement.h" #include "SVGURIReference.h" #include "SVGUseElement.h" #include "XLinkNames.h" @@ -68,7 +69,7 @@ static void parseKeyTimes(const String& parse, Vector<float>& result, bool verif String timeString = parseList[n]; bool ok; float time = timeString.toFloat(&ok); - if (!ok || time < 0 || time > 1.f) + if (!ok || time < 0 || time > 1) goto fail; if (verifyOrder) { if (!n) { @@ -97,25 +98,25 @@ static void parseKeySplines(const String& parse, Vector<UnitBezier>& result) bool delimParsed = false; while (cur < end) { delimParsed = false; - float posA = 0.0f; + float posA = 0; if (!parseNumber(cur, end, posA)) { result.clear(); return; } - float posB = 0.0f; + float posB = 0; if (!parseNumber(cur, end, posB)) { result.clear(); return; } - float posC = 0.0f; + float posC = 0; if (!parseNumber(cur, end, posC)) { result.clear(); return; } - float posD = 0.0f; + float posD = 0; if (!parseNumber(cur, end, posD, false)) { result.clear(); return; @@ -289,72 +290,56 @@ bool SVGAnimationElement::isAccumulated() const return value == sum && animationMode() != ToAnimation; } -bool SVGAnimationElement::hasValidTarget() const +bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* targetElement, const QualifiedName& attributeName) { - return targetElement(); -} - -bool SVGAnimationElement::attributeIsCSS(const String& attributeName) -{ - // FIXME: We should have a map of all SVG properties and their attribute types so we - // could validate animations better. The spec is very vague about this. - unsigned id = cssPropertyID(attributeName); - // SVG range - if (id >= CSSPropertyClipPath && id <= CSSPropertyWritingMode) - return true; - // Regular CSS properties also in SVG - return id == CSSPropertyColor || id == CSSPropertyDisplay || id == CSSPropertyOpacity - || (id >= CSSPropertyFont && id <= CSSPropertyFontWeight) - || id == CSSPropertyOverflow || id == CSSPropertyVisibility; -} - -bool SVGAnimationElement::targetAttributeIsCSS() const -{ - AttributeType type = attributeType(); - if (type == AttributeTypeCSS) - return true; - if (type == AttributeTypeXML) + ASSERT(targetElement); + if (!targetElement->isStyled()) return false; - return attributeIsCSS(attributeName()); + + return SVGStyledElement::isAnimatableCSSProperty(attributeName); } void SVGAnimationElement::setTargetAttributeAnimatedValue(const String& value) { - if (!hasValidTarget()) + if (!hasValidAttributeType()) return; - SVGElement* target = targetElement(); - String attributeName = this->attributeName(); - if (!target || attributeName.isEmpty() || value.isNull()) + SVGElement* targetElement = this->targetElement(); + QualifiedName attributeName = this->attributeName(); + if (!targetElement || attributeName == anyQName() || value.isNull()) return; // We don't want the instance tree to get rebuild. Instances are updated in the loop below. - if (target->isStyled()) - static_cast<SVGStyledElement*>(target)->setInstanceUpdatesBlocked(true); + if (targetElement->isStyled()) + static_cast<SVGStyledElement*>(targetElement)->setInstanceUpdatesBlocked(true); + bool attributeIsCSSProperty = isTargetAttributeCSSProperty(targetElement, attributeName); + // Stop animation, if attributeType is set to CSS by the user, but the attribute itself is not a CSS property. + if (!attributeIsCSSProperty && attributeType() == AttributeTypeCSS) + return; + ExceptionCode ec; - bool isCSS = targetAttributeIsCSS(); - if (isCSS) { + if (attributeIsCSSProperty) { // FIXME: This should set the override style, not the inline style. // Sadly override styles are not yet implemented. - target->style()->setProperty(attributeName, value, "", ec); + targetElement->style()->setProperty(attributeName.localName(), value, "", ec); } else { // FIXME: This should set the 'presentation' value, not the actual // attribute value. Whatever that means in practice. - target->setAttribute(attributeName, value, ec); + targetElement->setAttribute(attributeName, value, ec); } - if (target->isStyled()) - static_cast<SVGStyledElement*>(target)->setInstanceUpdatesBlocked(false); + if (targetElement->isStyled()) + static_cast<SVGStyledElement*>(targetElement)->setInstanceUpdatesBlocked(false); // If the target element is used in an <use> instance tree, update that as well. - const HashSet<SVGElementInstance*>& instances = target->instancesForElement(); + const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement(); const HashSet<SVGElementInstance*>::const_iterator end = instances.end(); for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) { SVGElement* shadowTreeElement = (*it)->shadowTreeElement(); if (!shadowTreeElement) continue; - if (isCSS) - shadowTreeElement->style()->setProperty(attributeName, value, "", ec); + if (attributeIsCSSProperty) + shadowTreeElement->style()->setProperty(attributeName.localName(), value, "", ec); else shadowTreeElement->setAttribute(attributeName, value, ec); (*it)->correspondingUseElement()->setNeedsStyleRecalc(); @@ -385,13 +370,13 @@ void SVGAnimationElement::calculateKeyTimesForCalcModePaced() // Normalize. for (unsigned n = 1; n < keyTimesForPaced.size() - 1; ++n) keyTimesForPaced[n] = keyTimesForPaced[n - 1] + keyTimesForPaced[n] / totalDistance; - keyTimesForPaced[keyTimesForPaced.size() - 1] = 1.f; + keyTimesForPaced[keyTimesForPaced.size() - 1] = 1; // Use key times calculated based on pacing instead of the user provided ones. m_keyTimes.swap(keyTimesForPaced); } -static inline double solveEpsilon(double duration) { return 1. / (200. * duration); } +static inline double solveEpsilon(double duration) { return 1 / (200 * duration); } unsigned SVGAnimationElement::calculateKeyTimesIndex(float percent) const { @@ -429,9 +414,9 @@ float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const float toKeyPoint = m_keyPoints[index + 1]; if (calcMode() == CalcModeDiscrete) - return percent == 1.0f ? toKeyPoint : fromKeyPoint; + return percent == 1 ? toKeyPoint : fromKeyPoint; - float keyPointPercent = percent == 1.0f ? 1.0f : (percent - fromPercent) / (toPercent - fromPercent); + float keyPointPercent = percent == 1 ? 1 : (percent - fromPercent) / (toPercent - fromPercent); if (calcMode() == CalcModeSpline) { ASSERT(m_keySplines.size() == m_keyPoints.size() - 1); @@ -446,7 +431,7 @@ void SVGAnimationElement::currentValuesFromKeyPoints(float percent, float& effec ASSERT(m_keyPoints.size() == m_keyTimes.size()); ASSERT(calcMode() != CalcModePaced); effectivePercent = calculatePercentFromKeyPoints(percent); - unsigned index = effectivePercent == 1.0f ? m_values.size() - 2 : static_cast<unsigned>(effectivePercent * (m_values.size() - 1)); + unsigned index = effectivePercent == 1 ? m_values.size() - 2 : static_cast<unsigned>(effectivePercent * (m_values.size() - 1)); from = m_values[index]; to = m_values[index + 1]; } @@ -468,10 +453,10 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float& unsigned index = calculateKeyTimesIndex(percent); if (calcMode == CalcModeDiscrete) { if (!keyTimesCount) - index = percent == 1.0f ? valuesCount - 1 : static_cast<unsigned>(percent * valuesCount); + index = percent == 1 ? valuesCount - 1 : static_cast<unsigned>(percent * valuesCount); from = m_values[index]; to = m_values[index]; - effectivePercent = 0.0f; + effectivePercent = 0; return; } @@ -491,7 +476,7 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float& from = m_values[index]; to = m_values[index + 1]; ASSERT(toPercent > fromPercent); - effectivePercent = percent == 1.0f ? 1.0f : (percent - fromPercent) / (toPercent - fromPercent); + effectivePercent = percent == 1 ? 1 : (percent - fromPercent) / (toPercent - fromPercent); if (calcMode == CalcModeSpline) { ASSERT(m_keySplines.size() == m_values.size() - 1); @@ -503,7 +488,7 @@ void SVGAnimationElement::startedActiveInterval() { m_animationValid = false; - if (!hasValidTarget()) + if (!hasValidAttributeType()) return; // These validations are appropriate for all animation modes. @@ -579,7 +564,5 @@ void SVGAnimationElement::endedActiveInterval() } } - -// vim:ts=4:noet #endif // ENABLE(SVG_ANIMATION) diff --git a/Source/WebCore/svg/SVGAnimationElement.h b/Source/WebCore/svg/SVGAnimationElement.h index 59d7f9e..8aa2cdb 100644 --- a/Source/WebCore/svg/SVGAnimationElement.h +++ b/Source/WebCore/svg/SVGAnimationElement.h @@ -55,8 +55,8 @@ public: virtual void beginElementAt(float offset); virtual void endElement(); virtual void endElementAt(float offset); - - static bool attributeIsCSS(const String& attributeName); + + static bool isTargetAttributeCSSProperty(SVGElement*, const QualifiedName&); protected: SVGAnimationElement(const QualifiedName&, Document*); @@ -75,12 +75,9 @@ protected: enum AnimationMode { NoAnimation, ToAnimation, ByAnimation, ValuesAnimation, FromToAnimation, FromByAnimation, PathAnimation }; AnimationMode animationMode() const; - - virtual bool hasValidTarget() const; String targetAttributeBaseValue() const; void setTargetAttributeAnimatedValue(const String&); - bool targetAttributeIsCSS() const; bool isAdditive() const; bool isAccumulated() const; diff --git a/Source/WebCore/svg/SVGCircleElement.cpp b/Source/WebCore/svg/SVGCircleElement.cpp index 6a3a0d4..2ab0640 100644 --- a/Source/WebCore/svg/SVGCircleElement.cpp +++ b/Source/WebCore/svg/SVGCircleElement.cpp @@ -90,12 +90,6 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName) if (!renderer) return; - if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { - renderer->setNeedsTransformUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); - return; - } - if (isLengthAttribute) { renderer->setNeedsPathUpdate(); RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); diff --git a/Source/WebCore/svg/SVGColor.cpp b/Source/WebCore/svg/SVGColor.cpp index 75900ad..911d02f 100644 --- a/Source/WebCore/svg/SVGColor.cpp +++ b/Source/WebCore/svg/SVGColor.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + * Copyright (C) Research In Motion Limited 2011. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,6 +20,7 @@ */ #include "config.h" + #if ENABLE(SVG) #include "SVGColor.h" @@ -28,28 +30,11 @@ namespace WebCore { -SVGColor::SVGColor() - : m_colorType(SVG_COLORTYPE_UNKNOWN) -{ -} - -SVGColor::SVGColor(const String& rgbColor) - : m_colorType(SVG_COLORTYPE_RGBCOLOR) -{ - setRGBColor(rgbColor); -} - -SVGColor::SVGColor(SVGColorType colorType) +SVGColor::SVGColor(const SVGColorType& colorType) : m_colorType(colorType) { } -SVGColor::SVGColor(const Color& c) - : m_color(c) - , m_colorType(SVG_COLORTYPE_RGBCOLOR) -{ -} - PassRefPtr<RGBColor> SVGColor::rgbColor() const { return RGBColor::create(m_color.rgb()); @@ -58,43 +43,111 @@ PassRefPtr<RGBColor> SVGColor::rgbColor() const void SVGColor::setRGBColor(const String& rgbColor, ExceptionCode& ec) { Color color = SVGColor::colorFromRGBColorString(rgbColor); - if (color.isValid()) - m_color = color; - else + if (!color.isValid()) { ec = SVGException::SVG_INVALID_VALUE_ERR; + return; + } + + m_color = color; + m_colorType = SVG_COLORTYPE_RGBCOLOR; + setNeedsStyleRecalc(); } Color SVGColor::colorFromRGBColorString(const String& colorString) { - String s = colorString.stripWhiteSpace(); - // FIXME: rework css parser so it is more svg aware + // FIXME: Rework css parser so it is more SVG aware. RGBA32 color; - if (CSSParser::parseColor(color, s)) + if (CSSParser::parseColor(color, colorString.stripWhiteSpace())) return color; return Color(); } -void SVGColor::setRGBColorICCColor(const String& /* rgbColor */, const String& /* iccColor */, ExceptionCode&) +void SVGColor::setRGBColorICCColor(const String& rgbColor, const String& iccColor, ExceptionCode& ec) { - // TODO: implement me! + if (rgbColor.isEmpty() || iccColor.isEmpty()) { + ec = SVGException::SVG_INVALID_VALUE_ERR; + return; + } + + // FIXME: No support for ICC colors. We're just ignoring it. + setRGBColor(rgbColor, ec); + if (ec) + return; + + m_colorType = SVG_COLORTYPE_RGBCOLOR_ICCCOLOR; + setNeedsStyleRecalc(); } -void SVGColor::setColor(unsigned short colorType, const String& /* rgbColor */ , const String& /* iccColor */, ExceptionCode&) +void SVGColor::setColor(unsigned short colorType, const String& rgbColor, const String& iccColor, ExceptionCode& ec) { - // TODO: implement me! - m_colorType = colorType; + if (colorType > SVG_COLORTYPE_CURRENTCOLOR) { + ec = SVGException::SVG_WRONG_TYPE_ERR; + return; + } + + bool requiresRGBColor = false; + bool requiresICCColor = false; + + SVGColorType type = static_cast<SVGColorType>(colorType); + switch (type) { + case SVG_COLORTYPE_UNKNOWN: + // Spec: It is invalid to attempt to define a new value of this type or to attempt to switch an existing value to this type. + ec = SVGException::SVG_INVALID_VALUE_ERR; + return; + case SVG_COLORTYPE_RGBCOLOR_ICCCOLOR: + requiresICCColor = true; + case SVG_COLORTYPE_RGBCOLOR: + requiresRGBColor = true; + break; + case SVG_COLORTYPE_CURRENTCOLOR: + break; + } + + // Spec: If colorType requires an RGBColor, then rgbColor must be a string that matches <color>; otherwise, rgbColor must be null. + if (requiresRGBColor && rgbColor.isEmpty()) { + ec = SVGException::SVG_INVALID_VALUE_ERR; + return; + } + + // Spec: If colorType requires an SVGICCColor, then iccColor must be a string that matches <icccolor>; otherwise, iccColor must be null. + if (requiresICCColor && iccColor.isEmpty()) { + ec = SVGException::SVG_INVALID_VALUE_ERR; + return; + } + + setNeedsStyleRecalc(); + m_colorType = type; + if (!requiresRGBColor) { + ASSERT(!requiresICCColor); + m_color = Color(); + return; + } + + if (requiresICCColor) + setRGBColorICCColor(rgbColor, iccColor, ec); + else + setRGBColor(rgbColor, ec); } String SVGColor::cssText() const { - if (m_colorType == SVG_COLORTYPE_RGBCOLOR) - return m_color.name(); - + switch (m_colorType) { + case SVG_COLORTYPE_UNKNOWN: + return String(); + case SVG_COLORTYPE_RGBCOLOR_ICCCOLOR: + case SVG_COLORTYPE_RGBCOLOR: + // FIXME: No ICC color support. + return m_color.serialized(); + case SVG_COLORTYPE_CURRENTCOLOR: + if (m_color.isValid()) + return m_color.serialized(); + return "currentColor"; + } + + ASSERT_NOT_REACHED(); return String(); } } -// vim:ts=4:noet #endif // ENABLE(SVG) - diff --git a/Source/WebCore/svg/SVGColor.h b/Source/WebCore/svg/SVGColor.h index 6d8b94e..58dc704 100644 --- a/Source/WebCore/svg/SVGColor.h +++ b/Source/WebCore/svg/SVGColor.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + * Copyright (C) Research In Motion Limited 2011. 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 @@ -20,9 +21,9 @@ #ifndef SVGColor_h #define SVGColor_h -#if ENABLE(SVG) -#include "CSSValue.h" +#if ENABLE(SVG) +#include "CSSMutableValue.h" #include "Color.h" #include <wtf/PassRefPtr.h> @@ -30,63 +31,62 @@ namespace WebCore { class RGBColor; -class SVGColor : public CSSValue { +class SVGColor : public CSSMutableValue { public: - static PassRefPtr<SVGColor> create(const String& color) + enum SVGColorType { + SVG_COLORTYPE_UNKNOWN = 0, + SVG_COLORTYPE_RGBCOLOR = 1, + SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2, + SVG_COLORTYPE_CURRENTCOLOR = 3 + }; + + static PassRefPtr<SVGColor> createFromString(const String& rgbColor) { - return adoptRef(new SVGColor(color)); + RefPtr<SVGColor> color = adoptRef(new SVGColor(SVG_COLORTYPE_RGBCOLOR)); + color->setColor(colorFromRGBColorString(rgbColor)); + return color.release(); } - static PassRefPtr<SVGColor> create(const Color& color) + + static PassRefPtr<SVGColor> createFromColor(const Color& rgbColor) { - return adoptRef(new SVGColor(color)); + RefPtr<SVGColor> color = adoptRef(new SVGColor(SVG_COLORTYPE_RGBCOLOR)); + color->setColor(rgbColor); + return color.release(); } + static PassRefPtr<SVGColor> createCurrentColor() { return adoptRef(new SVGColor(SVG_COLORTYPE_CURRENTCOLOR)); } - enum SVGColorType { - SVG_COLORTYPE_UNKNOWN = 0, - SVG_COLORTYPE_RGBCOLOR = 1, - SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2, - SVG_COLORTYPE_CURRENTCOLOR = 3 - }; - - // 'SVGColor' functions - unsigned short colorType() const { return m_colorType; } - + const Color& color() const { return m_color; } + const SVGColorType& colorType() const { return m_colorType; } PassRefPtr<RGBColor> rgbColor() const; static Color colorFromRGBColorString(const String&); - void setRGBColor(const String& rgbColor) { ExceptionCode ignored = 0; setRGBColor(rgbColor, ignored); } void setRGBColor(const String& rgbColor, ExceptionCode&); void setRGBColorICCColor(const String& rgbColor, const String& iccColor, ExceptionCode&); void setColor(unsigned short colorType, const String& rgbColor, const String& iccColor, ExceptionCode&); - const Color& color() const { return m_color; } - protected: - SVGColor(); - SVGColor(const String& color); - SVGColor(const Color&); + friend class CSSComputedStyleDeclaration; + SVGColor(const SVGColorType&); + virtual ~SVGColor() { } virtual String cssText() const; -private: - SVGColor(SVGColorType); - - static void create(int); // compile-time guard + void setColor(const Color& color) { m_color = color; } + void setColorType(const SVGColorType& type) { m_colorType = type; } +private: virtual bool isSVGColor() const { return true; } Color m_color; - unsigned short m_colorType; + SVGColorType m_colorType; }; } // namespace WebCore #endif // ENABLE(SVG) #endif // SVGColor_h - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGColor.idl b/Source/WebCore/svg/SVGColor.idl index d7af0e9..59bb630 100644 --- a/Source/WebCore/svg/SVGColor.idl +++ b/Source/WebCore/svg/SVGColor.idl @@ -22,25 +22,23 @@ module svg { interface [Conditional=SVG] SVGColor : CSSValue { - // Color Types - const unsigned short SVG_COLORTYPE_UNKNOWN = 0; - const unsigned short SVG_COLORTYPE_RGBCOLOR = 1; + const unsigned short SVG_COLORTYPE_UNKNOWN = 0; + const unsigned short SVG_COLORTYPE_RGBCOLOR = 1; const unsigned short SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2; - const unsigned short SVG_COLORTYPE_CURRENTCOLOR = 3; + const unsigned short SVG_COLORTYPE_CURRENTCOLOR = 3; readonly attribute unsigned short colorType; - readonly attribute RGBColor rgbColor; - /*readonly attribute SVGICCColor iccColor;*/ + readonly attribute RGBColor rgbColor; + // FIXME: readonly attribute SVGICCColor iccColor; - void setRGBColor(in DOMString rgbColor) - raises(SVGException); - void setRGBColorICCColor(in DOMString rgbColor, - in DOMString iccColor) - raises(SVGException); - void setColor(in unsigned short colorType, - in DOMString rgbColor, - in DOMString iccColor) - raises(SVGException); + [StrictTypeChecking, RequiresAllArguments=Raise] void setRGBColor(in DOMString rgbColor) + raises(DOMException, SVGException); + + [StrictTypeChecking, RequiresAllArguments=Raise] void setRGBColorICCColor(in DOMString rgbColor, in DOMString iccColor) + raises(DOMException, SVGException); + + [StrictTypeChecking, RequiresAllArguments=Raise] void setColor(in unsigned short colorType, in DOMString rgbColor, in DOMString iccColor) + raises(DOMException, SVGException); }; } diff --git a/Source/WebCore/svg/SVGCursorElement.cpp b/Source/WebCore/svg/SVGCursorElement.cpp index c49f799..12b47c9 100644 --- a/Source/WebCore/svg/SVGCursorElement.cpp +++ b/Source/WebCore/svg/SVGCursorElement.cpp @@ -94,8 +94,11 @@ void SVGCursorElement::addClient(SVGElement* element) void SVGCursorElement::removeClient(SVGElement* element) { - m_clients.remove(element); - element->cursorElementRemoved(); + HashSet<SVGElement*>::iterator it = m_clients.find(element); + if (it != m_clients.end()) { + m_clients.remove(it); + element->cursorElementRemoved(); + } } void SVGCursorElement::removeReferencedElement(SVGElement* element) diff --git a/Source/WebCore/svg/SVGDocumentExtensions.cpp b/Source/WebCore/svg/SVGDocumentExtensions.cpp index 7f7ba67..e47fe96 100644 --- a/Source/WebCore/svg/SVGDocumentExtensions.cpp +++ b/Source/WebCore/svg/SVGDocumentExtensions.cpp @@ -32,6 +32,7 @@ #include "FrameLoader.h" #include "Page.h" #include "SMILTimeContainer.h" +#include "SVGElement.h" #include "SVGSMILElement.h" #include "SVGSVGElement.h" #include "ScriptController.h" @@ -48,6 +49,7 @@ SVGDocumentExtensions::SVGDocumentExtensions(Document* document) SVGDocumentExtensions::~SVGDocumentExtensions() { + deleteAllValues(m_animatedElements); deleteAllValues(m_pendingResources); } @@ -135,6 +137,56 @@ bool SVGDocumentExtensions::sampleAnimationAtTime(const String& elementId, SVGSM #endif } +void SVGDocumentExtensions::addAnimationElementToTarget(SVGSMILElement* animationElement, SVGElement* targetElement) +{ + ASSERT(targetElement); + ASSERT(animationElement); + + if (HashSet<SVGSMILElement*>* animationElementsForTarget = m_animatedElements.get(targetElement)) { + animationElementsForTarget->add(animationElement); + return; + } + + HashSet<SVGSMILElement*>* animationElementsForTarget = new HashSet<SVGSMILElement*>; + animationElementsForTarget->add(animationElement); + m_animatedElements.set(targetElement, animationElementsForTarget); +} + +void SVGDocumentExtensions::removeAnimationElementFromTarget(SVGSMILElement* animationElement, SVGElement* targetElement) +{ + ASSERT(targetElement); + ASSERT(animationElement); + + HashMap<SVGElement*, HashSet<SVGSMILElement*>* >::iterator it = m_animatedElements.find(targetElement); + ASSERT(it != m_animatedElements.end()); + + HashSet<SVGSMILElement*>* animationElementsForTarget = it->second; + ASSERT(!animationElementsForTarget->isEmpty()); + + animationElementsForTarget->remove(animationElement); + if (animationElementsForTarget->isEmpty()) { + m_animatedElements.remove(it); + delete animationElementsForTarget; + } +} + +void SVGDocumentExtensions::removeAllAnimationElementsFromTarget(SVGElement* targetElement) +{ + ASSERT(targetElement); + HashSet<SVGSMILElement*>* animationElementsForTarget = m_animatedElements.take(targetElement); + if (!animationElementsForTarget) + return; +#if ENABLE(SVG_ANIMATION) + HashSet<SVGSMILElement*>::iterator it = animationElementsForTarget->begin(); + HashSet<SVGSMILElement*>::iterator end = animationElementsForTarget->end(); + for (; it != end; ++it) + (*it)->resetTargetElement(); + delete animationElementsForTarget; +#else + ASSERT_NOT_REACHED(); +#endif +} + // FIXME: Callers should probably use ScriptController::eventHandlerLineNumber() static int parserLineNumber(Document* document) { diff --git a/Source/WebCore/svg/SVGDocumentExtensions.h b/Source/WebCore/svg/SVGDocumentExtensions.h index 0ed62a9..4e28b0d 100644 --- a/Source/WebCore/svg/SVGDocumentExtensions.h +++ b/Source/WebCore/svg/SVGDocumentExtensions.h @@ -34,6 +34,7 @@ namespace WebCore { class Document; class RenderSVGResourceContainer; +class SVGElement; class SVGStyledElement; class SVGSMILElement; class SVGSVGElement; @@ -56,6 +57,10 @@ public: void pauseAnimations(); void unpauseAnimations(); bool sampleAnimationAtTime(const String& elementId, SVGSMILElement*, double time); + + void addAnimationElementToTarget(SVGSMILElement*, SVGElement*); + void removeAnimationElementFromTarget(SVGSMILElement*, SVGElement*); + void removeAllAnimationElementsFromTarget(SVGElement*); void reportWarning(const String&); void reportError(const String&); @@ -65,6 +70,7 @@ public: private: Document* m_document; // weak reference HashSet<SVGSVGElement*> m_timeContainers; // For SVG 1.2 support this will need to be made more general. + HashMap<SVGElement*, HashSet<SVGSMILElement*>* > m_animatedElements; HashMap<AtomicString, RenderSVGResourceContainer*> m_resources; HashMap<AtomicString, SVGPendingElements*> m_pendingResources; OwnPtr<SVGResourcesCache> m_resourcesCache; diff --git a/Source/WebCore/svg/SVGElement.cpp b/Source/WebCore/svg/SVGElement.cpp index 99134b2..4630ccb 100644 --- a/Source/WebCore/svg/SVGElement.cpp +++ b/Source/WebCore/svg/SVGElement.cpp @@ -82,6 +82,7 @@ SVGElement::~SVGElement() delete rareData; rareDataMap.remove(it); } + document()->accessSVGExtensions()->removeAllAnimationElementsFromTarget(this); } SVGElementRareData* SVGElement::rareSVGData() const @@ -117,6 +118,12 @@ void SVGElement::setXmlbase(const String& value, ExceptionCode&) setAttribute(XMLNames::baseAttr, value); } +void SVGElement::removedFromDocument() +{ + document()->accessSVGExtensions()->removeAllAnimationElementsFromTarget(this); + StyledElement::removedFromDocument(); +} + SVGSVGElement* SVGElement::ownerSVGElement() const { ContainerNode* n = parentOrHostNode(); @@ -371,6 +378,9 @@ void SVGElement::attributeChanged(Attribute* attr, bool preserveDecls) if (isSynchronizingSVGAttributes()) return; + if (isIdAttributeName(attr->name())) + document()->accessSVGExtensions()->removeAllAnimationElementsFromTarget(this); + // Changes to the style attribute are processed lazily (see Element::getAttribute() and related methods), // so we don't want changes to the style attribute to result in extra work here. if (attr->name() != HTMLNames::styleAttr) diff --git a/Source/WebCore/svg/SVGElement.h b/Source/WebCore/svg/SVGElement.h index ceb0973..380fa0e 100644 --- a/Source/WebCore/svg/SVGElement.h +++ b/Source/WebCore/svg/SVGElement.h @@ -118,6 +118,8 @@ protected: virtual void insertedIntoDocument(); virtual void attributeChanged(Attribute*, bool preserveDecls = false); virtual bool childShouldCreateRenderer(Node*) const; + + virtual void removedFromDocument(); SVGElementRareData* rareSVGData() const; SVGElementRareData* ensureRareSVGData(); diff --git a/Source/WebCore/svg/SVGEllipseElement.cpp b/Source/WebCore/svg/SVGEllipseElement.cpp index 129e1cd..73f921e 100644 --- a/Source/WebCore/svg/SVGEllipseElement.cpp +++ b/Source/WebCore/svg/SVGEllipseElement.cpp @@ -97,12 +97,6 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName) if (!renderer) return; - if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { - renderer->setNeedsTransformUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); - return; - } - if (isLengthAttribute) { renderer->setNeedsPathUpdate(); RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); diff --git a/Source/WebCore/svg/SVGFEBlendElement.cpp b/Source/WebCore/svg/SVGFEBlendElement.cpp index b0f580c..ff2f197 100644 --- a/Source/WebCore/svg/SVGFEBlendElement.cpp +++ b/Source/WebCore/svg/SVGFEBlendElement.cpp @@ -68,12 +68,24 @@ void SVGFEBlendElement::parseMappedAttribute(Attribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) +{ + FEBlend* blend = static_cast<FEBlend*>(effect); + if (attrName == SVGNames::modeAttr) + return blend->setBlendMode(static_cast<BlendModeType>(mode())); + + ASSERT_NOT_REACHED(); + return false; +} + void SVGFEBlendElement::svgAttributeChanged(const QualifiedName& attrName) { SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - if (attrName == SVGNames::modeAttr - || attrName == SVGNames::inAttr + if (attrName == SVGNames::modeAttr) + primitiveAttributeChanged(attrName); + + if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) invalidate(); } diff --git a/Source/WebCore/svg/SVGFEBlendElement.h b/Source/WebCore/svg/SVGFEBlendElement.h index c579ac5..b429d4b 100644 --- a/Source/WebCore/svg/SVGFEBlendElement.h +++ b/Source/WebCore/svg/SVGFEBlendElement.h @@ -36,6 +36,7 @@ private: SVGFEBlendElement(const QualifiedName&, Document*); virtual void parseMappedAttribute(Attribute*); + virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName); virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); virtual void fillAttributeToPropertyTypeMap(); diff --git a/Source/WebCore/svg/SVGFEColorMatrixElement.cpp b/Source/WebCore/svg/SVGFEColorMatrixElement.cpp index d3229d0..19acf0f 100644 --- a/Source/WebCore/svg/SVGFEColorMatrixElement.cpp +++ b/Source/WebCore/svg/SVGFEColorMatrixElement.cpp @@ -69,13 +69,26 @@ void SVGFEColorMatrixElement::parseMappedAttribute(Attribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +bool SVGFEColorMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) +{ + FEColorMatrix* colorMatrix = static_cast<FEColorMatrix*>(effect); + if (attrName == SVGNames::typeAttr) + return colorMatrix->setType(static_cast<ColorMatrixType>(type())); + if (attrName == SVGNames::valuesAttr) + return colorMatrix->setValues(values()); + + ASSERT_NOT_REACHED(); + return false; +} + void SVGFEColorMatrixElement::svgAttributeChanged(const QualifiedName& attrName) { SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); if (attrName == SVGNames::typeAttr - || attrName == SVGNames::inAttr || attrName == SVGNames::valuesAttr) + primitiveAttributeChanged(attrName); + if (attrName == SVGNames::inAttr) invalidate(); } diff --git a/Source/WebCore/svg/SVGFEColorMatrixElement.h b/Source/WebCore/svg/SVGFEColorMatrixElement.h index 7bff011..ec7ea9b 100644 --- a/Source/WebCore/svg/SVGFEColorMatrixElement.h +++ b/Source/WebCore/svg/SVGFEColorMatrixElement.h @@ -37,6 +37,7 @@ private: SVGFEColorMatrixElement(const QualifiedName&, Document*); virtual void parseMappedAttribute(Attribute*); + virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&); virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); virtual void fillAttributeToPropertyTypeMap(); diff --git a/Source/WebCore/svg/SVGFECompositeElement.cpp b/Source/WebCore/svg/SVGFECompositeElement.cpp index af738a9..1c40921 100644 --- a/Source/WebCore/svg/SVGFECompositeElement.cpp +++ b/Source/WebCore/svg/SVGFECompositeElement.cpp @@ -82,17 +82,38 @@ void SVGFECompositeElement::parseMappedAttribute(Attribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +bool SVGFECompositeElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) +{ + FEComposite* composite = static_cast<FEComposite*>(effect); + if (attrName == SVGNames::operatorAttr) + return composite->setOperation(static_cast<CompositeOperationType>(_operator())); + if (attrName == SVGNames::k1Attr) + return composite->setK1(k1()); + if (attrName == SVGNames::k2Attr) + return composite->setK2(k2()); + if (attrName == SVGNames::k3Attr) + return composite->setK3(k3()); + if (attrName == SVGNames::k4Attr) + return composite->setK4(k4()); + + ASSERT_NOT_REACHED(); + return false; +} + + void SVGFECompositeElement::svgAttributeChanged(const QualifiedName& attrName) { SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - if (attrName == SVGNames::inAttr - || attrName == SVGNames::in2Attr - || attrName == SVGNames::operatorAttr + if (attrName == SVGNames::operatorAttr || attrName == SVGNames::k1Attr || attrName == SVGNames::k2Attr || attrName == SVGNames::k3Attr || attrName == SVGNames::k4Attr) + primitiveAttributeChanged(attrName); + + if (attrName == SVGNames::inAttr + || attrName == SVGNames::in2Attr) invalidate(); } diff --git a/Source/WebCore/svg/SVGFECompositeElement.h b/Source/WebCore/svg/SVGFECompositeElement.h index a4a9617..6557d0b 100644 --- a/Source/WebCore/svg/SVGFECompositeElement.h +++ b/Source/WebCore/svg/SVGFECompositeElement.h @@ -37,6 +37,7 @@ private: SVGFECompositeElement(const QualifiedName&, Document*); virtual void parseMappedAttribute(Attribute*); + virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&); virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); virtual void fillAttributeToPropertyTypeMap(); diff --git a/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp b/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp index 07ebc41..4fa5e30 100644 --- a/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp +++ b/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp @@ -128,6 +128,28 @@ void SVGFEConvolveMatrixElement::parseMappedAttribute(Attribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +bool SVGFEConvolveMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) +{ + FEConvolveMatrix* convolveMatrix = static_cast<FEConvolveMatrix*>(effect); + if (attrName == SVGNames::edgeModeAttr) + return convolveMatrix->setEdgeMode(static_cast<EdgeModeType>(edgeMode())); + if (attrName == SVGNames::divisorAttr) + return convolveMatrix->setDivisor(divisor()); + if (attrName == SVGNames::biasAttr) + return convolveMatrix->setBias(bias()); + if (attrName == SVGNames::targetXAttr) + return convolveMatrix->setTargetOffset(IntPoint(targetX(), targetY())); + if (attrName == SVGNames::targetYAttr) + return convolveMatrix->setTargetOffset(IntPoint(targetX(), targetY())); + if (attrName == SVGNames::kernelUnitLengthAttr) + return convolveMatrix->setKernelUnitLength(FloatPoint(kernelUnitLengthX(), kernelUnitLengthY())); + if (attrName == SVGNames::preserveAlphaAttr) + return convolveMatrix->setPreserveAlpha(preserveAlpha()); + + ASSERT_NOT_REACHED(); + return false; +} + void SVGFEConvolveMatrixElement::setOrder(float x, float y) { setOrderXBaseValue(x); @@ -146,16 +168,18 @@ void SVGFEConvolveMatrixElement::svgAttributeChanged(const QualifiedName& attrNa { SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - if (attrName == SVGNames::inAttr - || attrName == SVGNames::orderAttr - || attrName == SVGNames::edgeModeAttr - || attrName == SVGNames::kernelMatrixAttr + if (attrName == SVGNames::edgeModeAttr || attrName == SVGNames::divisorAttr || attrName == SVGNames::biasAttr || attrName == SVGNames::targetXAttr || attrName == SVGNames::targetYAttr || attrName == SVGNames::kernelUnitLengthAttr || attrName == SVGNames::preserveAlphaAttr) + primitiveAttributeChanged(attrName); + + if (attrName == SVGNames::inAttr + || attrName == SVGNames::orderAttr + || attrName == SVGNames::kernelMatrixAttr) invalidate(); } diff --git a/Source/WebCore/svg/SVGFEConvolveMatrixElement.h b/Source/WebCore/svg/SVGFEConvolveMatrixElement.h index ccc45ce..42f093d 100644 --- a/Source/WebCore/svg/SVGFEConvolveMatrixElement.h +++ b/Source/WebCore/svg/SVGFEConvolveMatrixElement.h @@ -42,6 +42,7 @@ private: SVGFEConvolveMatrixElement(const QualifiedName&, Document*); virtual void parseMappedAttribute(Attribute*); + virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&); virtual void svgAttributeChanged(const QualifiedName&); virtual void fillAttributeToPropertyTypeMap(); virtual AttributeToPropertyTypeMap& attributeToPropertyTypeMap(); diff --git a/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp b/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp index 1e86097..a4c2a6b 100644 --- a/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp +++ b/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp @@ -97,7 +97,9 @@ bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect, } LightSource* lightSource = const_cast<LightSource*>(diffuseLighting->lightSource()); - const SVGFELightElement* lightElement = findLightElement(); + const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this); + ASSERT(lightSource); + ASSERT(lightElement); if (attrName == SVGNames::azimuthAttr) return lightSource->setAzimuth(lightElement->azimuth()); @@ -140,7 +142,7 @@ void SVGFEDiffuseLightingElement::svgAttributeChanged(const QualifiedName& attrN void SVGFEDiffuseLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName) { - if (findLightElement() != lightElement) + if (SVGFELightElement::findLightElement(this) != lightElement) return; // The light element has different attribute names. @@ -192,39 +194,23 @@ void SVGFEDiffuseLightingElement::fillAttributeToPropertyTypeMap() PassRefPtr<FilterEffect> SVGFEDiffuseLightingElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); - + if (!input1) return 0; - + + RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this); + if (!lightSource) + return 0; + RefPtr<RenderStyle> filterStyle = styleForRenderer(); Color color = filterStyle->svgStyle()->lightingColor(); - - RefPtr<FilterEffect> effect = FEDiffuseLighting::create(filter, color, surfaceScale(), diffuseConstant(), - kernelUnitLengthX(), kernelUnitLengthY(), findLight()); + + RefPtr<FilterEffect> effect = FEDiffuseLighting::create(filter, color, surfaceScale(), diffuseConstant(), + kernelUnitLengthX(), kernelUnitLengthY(), lightSource.release()); effect->inputEffects().append(input1); return effect.release(); } -SVGFELightElement* SVGFEDiffuseLightingElement::findLightElement() const -{ - for (Node* node = firstChild(); node; node = node->nextSibling()) { - if (node->hasTagName(SVGNames::feDistantLightTag) - || node->hasTagName(SVGNames::fePointLightTag) - || node->hasTagName(SVGNames::feSpotLightTag)) { - return static_cast<SVGFELightElement*>(node); - } - } - return 0; -} - -PassRefPtr<LightSource> SVGFEDiffuseLightingElement::findLight() const -{ - SVGFELightElement* lightNode = findLightElement(); - if (!lightNode) - return 0; - return lightNode->lightSource(); -} - } #endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEDiffuseLightingElement.h b/Source/WebCore/svg/SVGFEDiffuseLightingElement.h index 5f698c2..99dcfde 100644 --- a/Source/WebCore/svg/SVGFEDiffuseLightingElement.h +++ b/Source/WebCore/svg/SVGFEDiffuseLightingElement.h @@ -56,9 +56,6 @@ private: DECLARE_ANIMATED_NUMBER(SurfaceScale, surfaceScale) DECLARE_ANIMATED_NUMBER(KernelUnitLengthX, kernelUnitLengthX) DECLARE_ANIMATED_NUMBER(KernelUnitLengthY, kernelUnitLengthY) - - SVGFELightElement* findLightElement() const; - PassRefPtr<LightSource> findLight() const; }; } // namespace WebCore diff --git a/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp b/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp index b5f2e32..873f85a 100644 --- a/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp +++ b/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp @@ -79,15 +79,31 @@ void SVGFEDisplacementMapElement::parseMappedAttribute(Attribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) +{ + FEDisplacementMap* displacementMap = static_cast<FEDisplacementMap*>(effect); + if (attrName == SVGNames::xChannelSelectorAttr) + return displacementMap->setXChannelSelector(static_cast<ChannelSelectorType>(xChannelSelector())); + if (attrName == SVGNames::yChannelSelectorAttr) + return displacementMap->setYChannelSelector(static_cast<ChannelSelectorType>(yChannelSelector())); + if (attrName == SVGNames::scaleAttr) + return displacementMap->setScale(scale()); + + ASSERT_NOT_REACHED(); + return false; +} + 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) + primitiveAttributeChanged(attrName); + + if (attrName == SVGNames::inAttr + || attrName == SVGNames::in2Attr) invalidate(); } diff --git a/Source/WebCore/svg/SVGFEDisplacementMapElement.h b/Source/WebCore/svg/SVGFEDisplacementMapElement.h index c211de5..7aee539 100644 --- a/Source/WebCore/svg/SVGFEDisplacementMapElement.h +++ b/Source/WebCore/svg/SVGFEDisplacementMapElement.h @@ -38,6 +38,7 @@ private: SVGFEDisplacementMapElement(const QualifiedName& tagName, Document*); virtual void parseMappedAttribute(Attribute*); + virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName); virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); virtual void fillAttributeToPropertyTypeMap(); diff --git a/Source/WebCore/svg/SVGFELightElement.cpp b/Source/WebCore/svg/SVGFELightElement.cpp index 58a2f26..110011f 100644 --- a/Source/WebCore/svg/SVGFELightElement.cpp +++ b/Source/WebCore/svg/SVGFELightElement.cpp @@ -28,6 +28,7 @@ #include "RenderObject.h" #include "RenderSVGResource.h" #include "SVGFEDiffuseLightingElement.h" +#include "SVGFESpecularLightingElement.h" #include "SVGFilterElement.h" #include "SVGFilterPrimitiveStandardAttributes.h" #include "SVGNames.h" @@ -52,6 +53,26 @@ SVGFELightElement::SVGFELightElement(const QualifiedName& tagName, Document* doc { } +SVGFELightElement* SVGFELightElement::findLightElement(const SVGElement* svgElement) +{ + for (Node* node = svgElement->firstChild(); node; node = node->nextSibling()) { + if (node->hasTagName(SVGNames::feDistantLightTag) + || node->hasTagName(SVGNames::fePointLightTag) + || node->hasTagName(SVGNames::feSpotLightTag)) { + return static_cast<SVGFELightElement*>(node); + } + } + return 0; +} + +PassRefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement* svgElement) +{ + SVGFELightElement* lightNode = findLightElement(svgElement); + if (!lightNode) + return 0; + return lightNode->lightSource(); +} + void SVGFELightElement::parseMappedAttribute(Attribute* attr) { const String& value = attr->value(); @@ -105,9 +126,11 @@ void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName) SVGFEDiffuseLightingElement* diffuseLighting = static_cast<SVGFEDiffuseLightingElement*>(parent); diffuseLighting->lightElementAttributeChanged(this, attrName); return; + } else if (parent->hasTagName(SVGNames::feSpecularLightingTag)) { + SVGFESpecularLightingElement* specularLighting = static_cast<SVGFESpecularLightingElement*>(parent); + specularLighting->lightElementAttributeChanged(this, attrName); + return; } - // Handler for SpecularLighting has not implemented yet. - RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); } } diff --git a/Source/WebCore/svg/SVGFELightElement.h b/Source/WebCore/svg/SVGFELightElement.h index 606a499..1e88a49 100644 --- a/Source/WebCore/svg/SVGFELightElement.h +++ b/Source/WebCore/svg/SVGFELightElement.h @@ -32,6 +32,8 @@ namespace WebCore { class SVGFELightElement : public SVGElement { public: virtual PassRefPtr<LightSource> lightSource() const = 0; + static SVGFELightElement* findLightElement(const SVGElement*); + static PassRefPtr<LightSource> findLightSource(const SVGElement*); protected: SVGFELightElement(const QualifiedName&, Document*); diff --git a/Source/WebCore/svg/SVGFEMorphologyElement.cpp b/Source/WebCore/svg/SVGFEMorphologyElement.cpp index 1a44e3c..2b02b6a 100644 --- a/Source/WebCore/svg/SVGFEMorphologyElement.cpp +++ b/Source/WebCore/svg/SVGFEMorphologyElement.cpp @@ -86,13 +86,27 @@ void SVGFEMorphologyElement::parseMappedAttribute(Attribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +bool SVGFEMorphologyElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) +{ + FEMorphology* morphology = static_cast<FEMorphology*>(effect); + if (attrName == SVGNames::operatorAttr) + return morphology->setMorphologyOperator(static_cast<MorphologyOperatorType>(_operator())); + if (attrName == SVGNames::radiusAttr) + return (morphology->setRadiusX(radiusX()) || morphology->setRadiusY(radiusY())); + + ASSERT_NOT_REACHED(); + return false; +} + void SVGFEMorphologyElement::svgAttributeChanged(const QualifiedName& attrName) { SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - if (attrName == SVGNames::inAttr - || attrName == SVGNames::operatorAttr + if (attrName == SVGNames::operatorAttr || attrName == SVGNames::radiusAttr) + primitiveAttributeChanged(attrName); + + if (attrName == SVGNames::inAttr) invalidate(); } diff --git a/Source/WebCore/svg/SVGFEMorphologyElement.h b/Source/WebCore/svg/SVGFEMorphologyElement.h index 931288f..d7c1c16 100644 --- a/Source/WebCore/svg/SVGFEMorphologyElement.h +++ b/Source/WebCore/svg/SVGFEMorphologyElement.h @@ -38,6 +38,7 @@ private: SVGFEMorphologyElement(const QualifiedName&, Document*); virtual void parseMappedAttribute(Attribute*); + virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&); virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); virtual void fillAttributeToPropertyTypeMap(); diff --git a/Source/WebCore/svg/SVGFESpecularLightingElement.cpp b/Source/WebCore/svg/SVGFESpecularLightingElement.cpp index f4f2648..60684ed 100644 --- a/Source/WebCore/svg/SVGFESpecularLightingElement.cpp +++ b/Source/WebCore/svg/SVGFESpecularLightingElement.cpp @@ -89,18 +89,69 @@ void SVGFESpecularLightingElement::parseMappedAttribute(Attribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +bool SVGFESpecularLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) +{ + FESpecularLighting* specularLighting = static_cast<FESpecularLighting*>(effect); + if (attrName == SVGNames::surfaceScaleAttr) + return specularLighting->setSurfaceScale(surfaceScale()); + if (attrName == SVGNames::specularConstantAttr) + return specularLighting->setSpecularConstant(specularConstant()); + if (attrName == SVGNames::specularExponentAttr) + return specularLighting->setSpecularExponent(specularExponent()); + + LightSource* lightSource = const_cast<LightSource*>(specularLighting->lightSource()); + const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this); + ASSERT(lightSource); + ASSERT(lightElement); + + if (attrName == SVGNames::azimuthAttr) + return lightSource->setAzimuth(lightElement->azimuth()); + if (attrName == SVGNames::elevationAttr) + return lightSource->setElevation(lightElement->elevation()); + if (attrName == SVGNames::xAttr) + return lightSource->setX(lightElement->x()); + if (attrName == SVGNames::yAttr) + return lightSource->setY(lightElement->y()); + if (attrName == SVGNames::zAttr) + return lightSource->setZ(lightElement->z()); + if (attrName == SVGNames::pointsAtXAttr) + return lightSource->setPointsAtX(lightElement->pointsAtX()); + if (attrName == SVGNames::pointsAtYAttr) + return lightSource->setPointsAtY(lightElement->pointsAtY()); + if (attrName == SVGNames::pointsAtZAttr) + return lightSource->setPointsAtZ(lightElement->pointsAtZ()); + if (attrName == SVGNames::specularExponentAttr) + return lightSource->setSpecularExponent(lightElement->specularExponent()); + if (attrName == SVGNames::limitingConeAngleAttr) + return lightSource->setLimitingConeAngle(lightElement->limitingConeAngle()); + + ASSERT_NOT_REACHED(); + return false; +} + void SVGFESpecularLightingElement::svgAttributeChanged(const QualifiedName& attrName) { SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - if (attrName == SVGNames::inAttr - || attrName == SVGNames::surfaceScaleAttr + if (attrName == SVGNames::surfaceScaleAttr || attrName == SVGNames::specularConstantAttr || attrName == SVGNames::specularExponentAttr || attrName == SVGNames::kernelUnitLengthAttr) + primitiveAttributeChanged(attrName); + + if (attrName == SVGNames::inAttr) invalidate(); } +void SVGFESpecularLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName) +{ + if (SVGFELightElement::findLightElement(this) != lightElement) + return; + + // The light element has different attribute names so attrName can identify the requested attribute. + primitiveAttributeChanged(attrName); +} + void SVGFESpecularLightingElement::synchronizeProperty(const QualifiedName& attrName) { SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); @@ -147,33 +198,23 @@ void SVGFESpecularLightingElement::fillAttributeToPropertyTypeMap() attributeToPropertyTypeMap.set(SVGNames::kernelUnitLengthAttr, AnimatedNumberOptionalNumber); } -PassRefPtr<LightSource> SVGFESpecularLightingElement::findLights() const -{ - for (Node* node = firstChild(); node; node = node->nextSibling()) { - if (node->hasTagName(SVGNames::feDistantLightTag) - || node->hasTagName(SVGNames::fePointLightTag) - || node->hasTagName(SVGNames::feSpotLightTag)) { - SVGFELightElement* lightNode = static_cast<SVGFELightElement*>(node); - return lightNode->lightSource(); - } - } - - return 0; -} - PassRefPtr<FilterEffect> SVGFESpecularLightingElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); - + if (!input1) return 0; - - RefPtr<RenderStyle> filterStyle = styleForRenderer(); - + + RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this); + if (!lightSource) + return 0; + + RefPtr<RenderStyle> filterStyle = styleForRenderer(); + Color color = filterStyle->svgStyle()->lightingColor(); - RefPtr<FilterEffect> effect = FESpecularLighting::create(filter, color, surfaceScale(), specularConstant(), - specularExponent(), kernelUnitLengthX(), kernelUnitLengthY(), findLights()); + RefPtr<FilterEffect> effect = FESpecularLighting::create(filter, color, surfaceScale(), specularConstant(), + specularExponent(), kernelUnitLengthX(), kernelUnitLengthY(), lightSource.release()); effect->inputEffects().append(input1); return effect.release(); } diff --git a/Source/WebCore/svg/SVGFESpecularLightingElement.h b/Source/WebCore/svg/SVGFESpecularLightingElement.h index 9914123..cfceb44 100644 --- a/Source/WebCore/svg/SVGFESpecularLightingElement.h +++ b/Source/WebCore/svg/SVGFESpecularLightingElement.h @@ -25,6 +25,7 @@ #if ENABLE(SVG) && ENABLE(FILTERS) #include "FESpecularLighting.h" #include "SVGAnimatedNumber.h" +#include "SVGFELightElement.h" #include "SVGFilterPrimitiveStandardAttributes.h" namespace WebCore { @@ -32,11 +33,13 @@ namespace WebCore { class SVGFESpecularLightingElement : public SVGFilterPrimitiveStandardAttributes { public: static PassRefPtr<SVGFESpecularLightingElement> create(const QualifiedName&, Document*); + void lightElementAttributeChanged(const SVGFELightElement*, const QualifiedName&); private: SVGFESpecularLightingElement(const QualifiedName&, Document*); virtual void parseMappedAttribute(Attribute*); + virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&); virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); virtual void fillAttributeToPropertyTypeMap(); @@ -53,8 +56,6 @@ private: DECLARE_ANIMATED_NUMBER(SurfaceScale, surfaceScale) DECLARE_ANIMATED_NUMBER(KernelUnitLengthX, kernelUnitLengthX) DECLARE_ANIMATED_NUMBER(KernelUnitLengthY, kernelUnitLengthY) - - PassRefPtr<LightSource> findLights() const; }; } // namespace WebCore diff --git a/Source/WebCore/svg/SVGFETurbulenceElement.cpp b/Source/WebCore/svg/SVGFETurbulenceElement.cpp index 2eaf1fc..285b669 100644 --- a/Source/WebCore/svg/SVGFETurbulenceElement.cpp +++ b/Source/WebCore/svg/SVGFETurbulenceElement.cpp @@ -89,16 +89,34 @@ void SVGFETurbulenceElement::parseMappedAttribute(Attribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +bool SVGFETurbulenceElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) +{ + FETurbulence* turbulence = static_cast<FETurbulence*>(effect); + if (attrName == SVGNames::typeAttr) + return turbulence->setType(static_cast<TurbulenceType>(type())); + if (attrName == SVGNames::stitchTilesAttr) + return turbulence->setStitchTiles(stitchTiles()); + if (attrName == SVGNames::baseFrequencyAttr) + return (turbulence->setBaseFrequencyX(baseFrequencyX()) || turbulence->setBaseFrequencyY(baseFrequencyY())); + if (attrName == SVGNames::seedAttr) + return turbulence->setSeed(seed()); + if (attrName == SVGNames::numOctavesAttr) + return turbulence->setNumOctaves(numOctaves()); + + ASSERT_NOT_REACHED(); + return false; +} + void SVGFETurbulenceElement::svgAttributeChanged(const QualifiedName& attrName) { SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - + if (attrName == SVGNames::baseFrequencyAttr || attrName == SVGNames::numOctavesAttr || attrName == SVGNames::seedAttr || attrName == SVGNames::stitchTilesAttr || attrName == SVGNames::typeAttr) - invalidate(); + primitiveAttributeChanged(attrName); } void SVGFETurbulenceElement::synchronizeProperty(const QualifiedName& attrName) @@ -151,7 +169,7 @@ PassRefPtr<FilterEffect> SVGFETurbulenceElement::build(SVGFilterBuilder*, Filter if (baseFrequencyX() < 0 || baseFrequencyY() < 0) return 0; - return FETurbulence::create(filter, static_cast<TurbulanceType>(type()), baseFrequencyX(), + return FETurbulence::create(filter, static_cast<TurbulenceType>(type()), baseFrequencyX(), baseFrequencyY(), numOctaves(), seed(), stitchTiles() == SVG_STITCHTYPE_STITCH); } diff --git a/Source/WebCore/svg/SVGFETurbulenceElement.h b/Source/WebCore/svg/SVGFETurbulenceElement.h index 5e8a8b6..a2cd4f5 100644 --- a/Source/WebCore/svg/SVGFETurbulenceElement.h +++ b/Source/WebCore/svg/SVGFETurbulenceElement.h @@ -44,6 +44,7 @@ private: SVGFETurbulenceElement(const QualifiedName&, Document*); virtual void parseMappedAttribute(Attribute*); + virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName); virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); virtual void fillAttributeToPropertyTypeMap(); diff --git a/Source/WebCore/svg/SVGFilterElement.cpp b/Source/WebCore/svg/SVGFilterElement.cpp index 539d4df..a3b5e7c 100644 --- a/Source/WebCore/svg/SVGFilterElement.cpp +++ b/Source/WebCore/svg/SVGFilterElement.cpp @@ -214,7 +214,7 @@ void SVGFilterElement::fillAttributeToPropertyTypeMap() attributeToPropertyTypeMap.set(SVGNames::widthAttr, AnimatedLength); attributeToPropertyTypeMap.set(SVGNames::heightAttr, AnimatedLength); attributeToPropertyTypeMap.set(SVGNames::filterResAttr, AnimatedNumberOptionalNumber); - attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedEnumeration); + attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedString); } void SVGFilterElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) diff --git a/Source/WebCore/svg/SVGFont.cpp b/Source/WebCore/svg/SVGFont.cpp index a92b9b6..e02fced 100644 --- a/Source/WebCore/svg/SVGFont.cpp +++ b/Source/WebCore/svg/SVGFont.cpp @@ -362,7 +362,7 @@ static void floatWidthMissingGlyphCallback(const TextRun& run, SVGTextRunWalkerM Font font(fontDescription, 0, 0); // spacing handled by SVG text code. font.update(data.font->fontSelector()); - data.length += font.floatWidth(run); + data.length += font.width(run); } @@ -573,9 +573,9 @@ void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run, font.drawText(context, fallbackCharacterRun, currentPoint); if (isVerticalText) - currentPoint.move(0.0f, font.floatWidth(fallbackCharacterRun)); + currentPoint.move(0.0f, font.width(fallbackCharacterRun)); else - currentPoint.move(font.floatWidth(fallbackCharacterRun), 0.0f); + currentPoint.move(font.width(fallbackCharacterRun), 0.0f); fallbackCharacterIndex++; } diff --git a/Source/WebCore/svg/SVGForeignObjectElement.cpp b/Source/WebCore/svg/SVGForeignObjectElement.cpp index f2175ac..7c48bf2 100644 --- a/Source/WebCore/svg/SVGForeignObjectElement.cpp +++ b/Source/WebCore/svg/SVGForeignObjectElement.cpp @@ -96,12 +96,6 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName) if (!renderer) return; - if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { - renderer->setNeedsTransformUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); - return; - } - if (isLengthAttribute || SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) diff --git a/Source/WebCore/svg/SVGGElement.cpp b/Source/WebCore/svg/SVGGElement.cpp index 233aa74..f7a48ec 100644 --- a/Source/WebCore/svg/SVGGElement.cpp +++ b/Source/WebCore/svg/SVGGElement.cpp @@ -66,12 +66,6 @@ void SVGGElement::svgAttributeChanged(const QualifiedName& attrName) if (!renderer) return; - if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { - renderer->setNeedsTransformUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); - return; - } - if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); @@ -93,6 +87,17 @@ void SVGGElement::synchronizeProperty(const QualifiedName& attrName) SVGTests::synchronizeProperties(this, attrName); } +AttributeToPropertyTypeMap& SVGGElement::attributeToPropertyTypeMap() +{ + DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ()); + return s_attributeToPropertyTypeMap; +} + +void SVGGElement::fillAttributeToPropertyTypeMap() +{ + SVGStyledTransformableElement::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap()); +} + RenderObject* SVGGElement::createRenderer(RenderArena* arena, RenderStyle* style) { // SVG 1.1 testsuite explicitely uses constructs like <g display="none"><linearGradient> diff --git a/Source/WebCore/svg/SVGGElement.h b/Source/WebCore/svg/SVGGElement.h index 3c00b34..c306f4a 100644 --- a/Source/WebCore/svg/SVGGElement.h +++ b/Source/WebCore/svg/SVGGElement.h @@ -50,6 +50,8 @@ private: virtual void parseMappedAttribute(Attribute*); virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); + virtual void fillAttributeToPropertyTypeMap(); + virtual AttributeToPropertyTypeMap& attributeToPropertyTypeMap(); virtual bool rendererIsNeeded(RenderStyle*); diff --git a/Source/WebCore/svg/SVGHKernElement.cpp b/Source/WebCore/svg/SVGHKernElement.cpp index 4632378..df92d34 100644 --- a/Source/WebCore/svg/SVGHKernElement.cpp +++ b/Source/WebCore/svg/SVGHKernElement.cpp @@ -52,6 +52,7 @@ void SVGHKernElement::insertedIntoDocument() if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode)) element->invalidateGlyphCache(); } + SVGElement::insertedIntoDocument(); } void SVGHKernElement::removedFromDocument() @@ -61,6 +62,7 @@ void SVGHKernElement::removedFromDocument() if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode)) element->invalidateGlyphCache(); } + SVGElement::removedFromDocument(); } void SVGHKernElement::buildHorizontalKerningPair(KerningPairVector& kerningPairs) diff --git a/Source/WebCore/svg/SVGImageElement.cpp b/Source/WebCore/svg/SVGImageElement.cpp index 784c1ab..21bb392 100644 --- a/Source/WebCore/svg/SVGImageElement.cpp +++ b/Source/WebCore/svg/SVGImageElement.cpp @@ -112,12 +112,6 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName) if (!renderer) return; - if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { - renderer->setNeedsTransformUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); - return; - } - if (isLengthAttribute) { renderer->updateFromElement(); RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false); diff --git a/Source/WebCore/svg/SVGImageLoader.cpp b/Source/WebCore/svg/SVGImageLoader.cpp index 17e9004..7c60191 100644 --- a/Source/WebCore/svg/SVGImageLoader.cpp +++ b/Source/WebCore/svg/SVGImageLoader.cpp @@ -49,7 +49,7 @@ void SVGImageLoader::dispatchLoadEvent() String SVGImageLoader::sourceURI(const AtomicString& attr) const { - return KURL(element()->baseURI(), stripLeadingAndTrailingHTMLSpaces(attr)).string(); + return element()->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(attr)); } } diff --git a/Source/WebCore/svg/SVGLineElement.cpp b/Source/WebCore/svg/SVGLineElement.cpp index 2e435c5..c3d5f0b 100644 --- a/Source/WebCore/svg/SVGLineElement.cpp +++ b/Source/WebCore/svg/SVGLineElement.cpp @@ -93,12 +93,6 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName) if (!renderer) return; - if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { - renderer->setNeedsTransformUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); - return; - } - if (isLengthAttribute) { renderer->setNeedsPathUpdate(); RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); diff --git a/Source/WebCore/svg/SVGPaint.cpp b/Source/WebCore/svg/SVGPaint.cpp index 76c13d5..c9e08db 100644 --- a/Source/WebCore/svg/SVGPaint.cpp +++ b/Source/WebCore/svg/SVGPaint.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) Research In Motion Limited 2010-2011. 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 @@ -24,96 +24,152 @@ #if ENABLE(SVG) #include "SVGPaint.h" +#include "SVGException.h" #include "SVGURIReference.h" +#include <wtf/text/StringConcatenate.h> namespace WebCore { -SVGPaint::SVGPaint() - : m_paintType(SVG_PAINTTYPE_UNKNOWN) +static inline SVGColor::SVGColorType colorTypeForPaintType(const SVGPaint::SVGPaintType& paintType) { + switch (paintType) { + case SVGPaint::SVG_PAINTTYPE_NONE: + case SVGPaint::SVG_PAINTTYPE_UNKNOWN: + case SVGPaint::SVG_PAINTTYPE_URI: + case SVGPaint::SVG_PAINTTYPE_URI_NONE: + return SVGColor::SVG_COLORTYPE_UNKNOWN; + case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR: + case SVGPaint::SVG_PAINTTYPE_RGBCOLOR: + return SVGColor::SVG_COLORTYPE_RGBCOLOR; + case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: + case SVGPaint::SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR: + return SVGColor::SVG_COLORTYPE_RGBCOLOR_ICCCOLOR; + case SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR: + case SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR: + return SVGColor::SVG_COLORTYPE_CURRENTCOLOR; + } + + ASSERT_NOT_REACHED(); + return SVGColor::SVG_COLORTYPE_UNKNOWN; } -SVGPaint::SVGPaint(const String& uri) - : m_paintType(SVG_PAINTTYPE_URI_RGBCOLOR) -{ - setUri(uri); -} - -SVGPaint::SVGPaint(SVGPaintType paintType) - : m_paintType(paintType) -{ -} - -SVGPaint::SVGPaint(SVGPaintType paintType, const String& uri, const String& rgbPaint, const String&) - : SVGColor(rgbPaint) +SVGPaint::SVGPaint(const SVGPaintType& paintType, String uri) + : SVGColor(colorTypeForPaintType(paintType)) , m_paintType(paintType) + , m_uri(uri) { - setUri(uri); -} - -SVGPaint::SVGPaint(const Color& c) - : SVGColor(c) - , m_paintType(SVG_PAINTTYPE_RGBCOLOR) -{ -} - -SVGPaint::SVGPaint(const String& uri, const Color& c) - : SVGColor(c) - , m_paintType(SVG_PAINTTYPE_URI_RGBCOLOR) -{ - setUri(uri); -} - -SVGPaint* SVGPaint::defaultFill() -{ - static SVGPaint* staticDefaultFill = create(Color::black).releaseRef(); - return staticDefaultFill; -} - -SVGPaint* SVGPaint::defaultStroke() -{ - static SVGPaint* staticDefaultStroke = create(SVG_PAINTTYPE_NONE).releaseRef(); - return staticDefaultStroke; -} - -String SVGPaint::uri() const -{ - return m_uri; } void SVGPaint::setUri(const String& uri) { + // Spec: Sets the paintType to SVG_PAINTTYPE_URI_NONE and sets uri to the specified value. m_uri = uri; + m_paintType = SVG_PAINTTYPE_URI_NONE; + setColor(Color()); + setColorType(colorTypeForPaintType(m_paintType)); + setNeedsStyleRecalc(); } -void SVGPaint::setPaint(SVGPaintType paintType, const String& uri, const String& rgbPaint, const String&, ExceptionCode&) +void SVGPaint::setPaint(unsigned short paintType, const String& uri, const String& rgbColor, const String& iccColor, ExceptionCode& ec) { - m_paintType = paintType; - - if (m_paintType == SVG_PAINTTYPE_URI) - setUri(uri); - else if (m_paintType == SVG_PAINTTYPE_RGBCOLOR) - setRGBColor(rgbPaint); + if ((paintType > SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR && paintType < SVG_PAINTTYPE_NONE) || paintType > SVG_PAINTTYPE_URI) { + ec = SVGException::SVG_WRONG_TYPE_ERR; + return; + } + + bool requiresURI = false; + + SVGPaintType type = static_cast<SVGPaintType>(paintType); + switch (type) { + case SVG_PAINTTYPE_UNKNOWN: + // Spec: It is invalid to attempt to define a new value of this type or to attempt to switch an existing value to this type. + ec = SVGException::SVG_INVALID_VALUE_ERR; + return; + case SVG_PAINTTYPE_RGBCOLOR: + case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR: + case SVG_PAINTTYPE_NONE: + case SVG_PAINTTYPE_CURRENTCOLOR: + break; + case SVG_PAINTTYPE_URI_NONE: + case SVG_PAINTTYPE_URI_CURRENTCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: + case SVG_PAINTTYPE_URI: + requiresURI = true; + break; + }; + + // Spec: If paintType requires a URI, then uri must be non-null; otherwise, uri must be null. + if (requiresURI && uri.isEmpty()) { + ec = SVGException::SVG_INVALID_VALUE_ERR; + return; + } + + SVGColor::SVGColorType colorType = colorTypeForPaintType(type); + if (colorType == SVGColor::SVG_COLORTYPE_UNKNOWN) { + // The standard setColor() code path used in the else branch + // raises an exception when attempting to switch to an unknown color type. + // Here we explicitely want to reset to Color() and an unknown type, so force it. + setColorType(colorType); + setColor(Color()); + } else { + setColor(colorType, rgbColor, iccColor, ec); + if (ec) + return; + } + + m_paintType = type; + m_uri = requiresURI ? uri : String(); + setNeedsStyleRecalc(); } String SVGPaint::cssText() const { - if (m_paintType == SVG_PAINTTYPE_NONE) + switch (m_paintType) { + case SVG_PAINTTYPE_UNKNOWN: + case SVG_PAINTTYPE_RGBCOLOR: + case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR: + case SVG_PAINTTYPE_CURRENTCOLOR: + return SVGColor::cssText(); + case SVG_PAINTTYPE_NONE: return "none"; - if (m_paintType == SVG_PAINTTYPE_CURRENTCOLOR) - return "currentColor"; - if (m_paintType == SVG_PAINTTYPE_URI) - return "url(" + m_uri + ")"; - - return SVGColor::cssText(); + case SVG_PAINTTYPE_URI_NONE: + return makeString(m_uri, " none"); + case SVG_PAINTTYPE_URI_CURRENTCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: { + String color = SVGColor::cssText(); + if (color.isEmpty()) + return m_uri; + return makeString(m_uri, ' ', color); + } + case SVG_PAINTTYPE_URI: + return m_uri; + }; + + ASSERT_NOT_REACHED(); + return String(); } bool SVGPaint::matchesTargetURI(const String& referenceId) { - if (m_paintType != SVG_PAINTTYPE_URI && m_paintType != SVG_PAINTTYPE_URI_RGBCOLOR) + switch (m_paintType) { + case SVG_PAINTTYPE_UNKNOWN: + case SVG_PAINTTYPE_RGBCOLOR: + case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR: + case SVG_PAINTTYPE_CURRENTCOLOR: + case SVG_PAINTTYPE_NONE: return false; - - return referenceId == SVGURIReference::getTarget(m_uri); + case SVG_PAINTTYPE_URI_NONE: + case SVG_PAINTTYPE_URI_CURRENTCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: + case SVG_PAINTTYPE_URI: + return referenceId == SVGURIReference::getTarget(m_uri); + } + + ASSERT_NOT_REACHED(); + return false; } } diff --git a/Source/WebCore/svg/SVGPaint.h b/Source/WebCore/svg/SVGPaint.h index 9b66295..5cacf91 100644 --- a/Source/WebCore/svg/SVGPaint.h +++ b/Source/WebCore/svg/SVGPaint.h @@ -2,6 +2,7 @@ * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmial.com> + * Copyright (C) Research In Motion Limited 2011. 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 @@ -21,9 +22,10 @@ #ifndef SVGPaint_h #define SVGPaint_h + #if ENABLE(SVG) -#include "PlatformString.h" #include "SVGColor.h" +#include <wtf/text/WTFString.h> namespace WebCore { @@ -42,49 +44,63 @@ public: SVG_PAINTTYPE_URI = 107 }; - static PassRefPtr<SVGPaint> create() + static PassRefPtr<SVGPaint> createUnknown() { - return adoptRef(new SVGPaint); + return adoptRef(new SVGPaint(SVG_PAINTTYPE_UNKNOWN)); } - static PassRefPtr<SVGPaint> create(SVGPaintType type) + + static PassRefPtr<SVGPaint> createNone() { - return adoptRef(new SVGPaint(type)); + return adoptRef(new SVGPaint(SVG_PAINTTYPE_NONE)); } - static PassRefPtr<SVGPaint> create(const Color& color) + + static PassRefPtr<SVGPaint> createCurrentColor() { - return adoptRef(new SVGPaint(color)); + return adoptRef(new SVGPaint(SVG_PAINTTYPE_CURRENTCOLOR)); } - static PassRefPtr<SVGPaint> create(SVGPaintType type, const String& uri) + + static PassRefPtr<SVGPaint> createColor(const Color& color) + { + RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(SVG_PAINTTYPE_RGBCOLOR)); + paint->setColor(color); + return paint.release(); + } + + static PassRefPtr<SVGPaint> createURI(const String& uri) { - return adoptRef(new SVGPaint(type, uri, String(), String())); + RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(SVG_PAINTTYPE_URI, uri)); + return paint.release(); } - static PassRefPtr<SVGPaint> create(const String& uri, const Color& color) + + static PassRefPtr<SVGPaint> createURIAndColor(const String& uri, const Color& color) { - return adoptRef(new SVGPaint(uri, color)); + RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(SVG_PAINTTYPE_URI_RGBCOLOR, uri)); + paint->setColor(color); + return paint.release(); } - // 'SVGPaint' functions - SVGPaintType paintType() const { return m_paintType; } - String uri() const; + const SVGPaintType& paintType() const { return m_paintType; } + String uri() const { return m_uri; } void setUri(const String&); - void setPaint(SVGPaintType, const String& uri, const String& rgbPaint, const String& iccPaint, ExceptionCode&); - - static SVGPaint* defaultFill(); - static SVGPaint* defaultStroke(); + void setPaint(unsigned short paintType, const String& uri, const String& rgbColor, const String& iccColor, ExceptionCode&); bool matchesTargetURI(const String& referenceId); private: - SVGPaint(); - SVGPaint(const String& uri); - SVGPaint(SVGPaintType); - SVGPaint(SVGPaintType, const String& uri, const String& rgbPaint, const String& iccPaint); - SVGPaint(const Color& c); - SVGPaint(const String& uri, const Color& c); + friend class CSSComputedStyleDeclaration; - virtual bool isSVGPaint() const { return true; } + static PassRefPtr<SVGPaint> create(const SVGPaintType& type, const String& uri, const Color& color) + { + RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(type, uri)); + paint->setColor(color); + return paint.release(); + } +private: + SVGPaint(const SVGPaintType&, String uri = String()); + + virtual bool isSVGPaint() const { return true; } virtual String cssText() const; SVGPaintType m_paintType; diff --git a/Source/WebCore/svg/SVGPaint.idl b/Source/WebCore/svg/SVGPaint.idl index 426b762..b87fd34 100644 --- a/Source/WebCore/svg/SVGPaint.idl +++ b/Source/WebCore/svg/SVGPaint.idl @@ -26,27 +26,23 @@ module svg { interface [Conditional=SVG] SVGPaint : SVGColor { - // SVGPaintType - const unsigned short SVG_PAINTTYPE_UNKNOWN = 0; - const unsigned short SVG_PAINTTYPE_RGBCOLOR = 1; - const unsigned short SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR = 2; - const unsigned short SVG_PAINTTYPE_NONE = 101; - const unsigned short SVG_PAINTTYPE_CURRENTCOLOR = 102; - const unsigned short SVG_PAINTTYPE_URI_NONE = 103; - const unsigned short SVG_PAINTTYPE_URI_CURRENTCOLOR = 104; - const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR = 105; + const unsigned short SVG_PAINTTYPE_UNKNOWN = 0; + const unsigned short SVG_PAINTTYPE_RGBCOLOR = 1; + const unsigned short SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR = 2; + const unsigned short SVG_PAINTTYPE_NONE = 101; + const unsigned short SVG_PAINTTYPE_CURRENTCOLOR = 102; + const unsigned short SVG_PAINTTYPE_URI_NONE = 103; + const unsigned short SVG_PAINTTYPE_URI_CURRENTCOLOR = 104; + const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR = 105; const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR = 106; - const unsigned short SVG_PAINTTYPE_URI = 107; + const unsigned short SVG_PAINTTYPE_URI = 107; - readonly attribute SVGPaintType paintType; + readonly attribute unsigned short paintType; readonly attribute DOMString uri; - void setUri(in DOMString uri); - void setPaint(in SVGPaintType paintType, - in DOMString uri, - in DOMString rgbColor, - in DOMString iccColor) - raises(SVGException); + [StrictTypeChecking, RequiresAllArguments=Raise] void setUri(in DOMString uri); + [StrictTypeChecking, RequiresAllArguments=Raise] void setPaint(in unsigned short paintType, in DOMString uri, in DOMString rgbColor, in DOMString iccColor) + raises(DOMException, SVGException); }; } diff --git a/Source/WebCore/svg/SVGPathElement.cpp b/Source/WebCore/svg/SVGPathElement.cpp index c56873b..e798eaf 100644 --- a/Source/WebCore/svg/SVGPathElement.cpp +++ b/Source/WebCore/svg/SVGPathElement.cpp @@ -230,12 +230,6 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName) if (!renderer) return; - if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { - renderer->setNeedsTransformUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); - return; - } - if (attrName == SVGNames::pathLengthAttr || SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) diff --git a/Source/WebCore/svg/SVGPolyElement.cpp b/Source/WebCore/svg/SVGPolyElement.cpp index 8a70347..331e5ec 100644 --- a/Source/WebCore/svg/SVGPolyElement.cpp +++ b/Source/WebCore/svg/SVGPolyElement.cpp @@ -76,12 +76,6 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName) if (!renderer) return; - if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { - renderer->setNeedsTransformUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); - return; - } - if (attrName == SVGNames::pointsAttr) { renderer->setNeedsPathUpdate(); RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); diff --git a/Source/WebCore/svg/SVGPreserveAspectRatio.cpp b/Source/WebCore/svg/SVGPreserveAspectRatio.cpp index 3f1172d..2ebcc1f 100644 --- a/Source/WebCore/svg/SVGPreserveAspectRatio.cpp +++ b/Source/WebCore/svg/SVGPreserveAspectRatio.cpp @@ -247,15 +247,14 @@ void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRe } } -// FIXME: We should use floats here, like everywhere else! -AffineTransform SVGPreserveAspectRatio::getCTM(double logicX, double logicY, double logicWidth, double logicHeight, double physWidth, double physHeight) const +AffineTransform SVGPreserveAspectRatio::getCTM(float logicX, float logicY, float logicWidth, float logicHeight, float physWidth, float physHeight) const { AffineTransform transform; if (m_align == SVG_PRESERVEASPECTRATIO_UNKNOWN) return transform; - double logicalRatio = logicWidth / logicHeight; - double physRatio = physWidth / physHeight; + float logicalRatio = logicWidth / logicHeight; + float physRatio = physWidth / physHeight; if (m_align == SVG_PRESERVEASPECTRATIO_NONE) { transform.scaleNonUniform(physWidth / logicWidth, physHeight / logicHeight); diff --git a/Source/WebCore/svg/SVGPreserveAspectRatio.h b/Source/WebCore/svg/SVGPreserveAspectRatio.h index bf00ee4..bdee15c 100644 --- a/Source/WebCore/svg/SVGPreserveAspectRatio.h +++ b/Source/WebCore/svg/SVGPreserveAspectRatio.h @@ -62,9 +62,9 @@ public: void transformRect(FloatRect& destRect, FloatRect& srcRect); - AffineTransform getCTM(double logicX, double logicY, - double logicWidth, double logicHeight, - double physWidth, double physHeight) const; + AffineTransform getCTM(float logicX, float logicY, + float logicWidth, float logicHeight, + float physWidth, float physHeight) const; template<class Consumer> static bool parsePreserveAspectRatio(Consumer* consumer, const String& value, bool validate = true) diff --git a/Source/WebCore/svg/SVGRectElement.cpp b/Source/WebCore/svg/SVGRectElement.cpp index 10c5743..2c6ee87 100644 --- a/Source/WebCore/svg/SVGRectElement.cpp +++ b/Source/WebCore/svg/SVGRectElement.cpp @@ -110,12 +110,6 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) if (!renderer) return; - if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { - renderer->setNeedsTransformUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); - return; - } - if (isLengthAttribute) { renderer->setNeedsPathUpdate(); RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); diff --git a/Source/WebCore/svg/SVGSVGElement.cpp b/Source/WebCore/svg/SVGSVGElement.cpp index e2540e3..0778bb7 100644 --- a/Source/WebCore/svg/SVGSVGElement.cpp +++ b/Source/WebCore/svg/SVGSVGElement.cpp @@ -129,20 +129,12 @@ void SVGSVGElement::setContentStyleType(const AtomicString& type) FloatRect SVGSVGElement::viewport() const { - double x = 0; - double y = 0; - if (!isOutermostSVG()) { - x = this->x().value(this); - y = this->y().value(this); - } - float w = width().value(this); - float h = height().value(this); - AffineTransform viewBox = viewBoxToViewTransform(w, h); - double wDouble = w; - double hDouble = h; - viewBox.map(x, y, x, y); - viewBox.map(w, h, wDouble, hDouble); - return FloatRect::narrowPrecision(x, y, wDouble, hDouble); + FloatRect viewRectangle; + if (!isOutermostSVG()) + viewRectangle.setLocation(FloatPoint(x().value(this), y().value(this))); + + viewRectangle.setSize(FloatSize(width().value(this), height().value(this))); + return viewBoxToViewTransform(viewRectangle.width(), viewRectangle.height()).mapRect(viewRectangle); } int SVGSVGElement::relativeWidthValue() const diff --git a/Source/WebCore/svg/SVGScriptElement.cpp b/Source/WebCore/svg/SVGScriptElement.cpp index babb1e7..00b85a5 100644 --- a/Source/WebCore/svg/SVGScriptElement.cpp +++ b/Source/WebCore/svg/SVGScriptElement.cpp @@ -35,9 +35,9 @@ namespace WebCore { DEFINE_ANIMATED_STRING(SVGScriptElement, XLinkNames::hrefAttr, Href, href) DEFINE_ANIMATED_BOOLEAN(SVGScriptElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) -inline SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document* document, bool wasInsertedByParser, bool wasAlreadyStarted) +inline SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document* document, bool wasInsertedByParser, bool alreadyStarted) : SVGElement(tagName, document) - , ScriptElement(this, wasInsertedByParser, wasAlreadyStarted) + , ScriptElement(this, wasInsertedByParser, alreadyStarted) { } @@ -72,7 +72,7 @@ void SVGScriptElement::svgAttributeChanged(const QualifiedName& 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() && !haveFiredLoadEvent() && !wasInsertedByParser()) { + if (!externalResourcesRequiredBaseValue() && !haveFiredLoadEvent() && !isParserInserted()) { setHaveFiredLoadEvent(true); ASSERT(haveLoadedRequiredResources()); @@ -111,9 +111,9 @@ void SVGScriptElement::fillAttributeToPropertyTypeMap() void SVGScriptElement::insertedIntoDocument() { SVGElement::insertedIntoDocument(); - ScriptElement::insertedIntoDocument(sourceAttributeValue()); + ScriptElement::insertedIntoDocument(); - if (wasInsertedByParser()) + if (isParserInserted()) return; // Eventually send SVGLoad event now for the dynamically inserted script element @@ -142,7 +142,6 @@ bool SVGScriptElement::isURLAttribute(Attribute* attr) const void SVGScriptElement::finishParsingChildren() { - ScriptElement::finishParsingChildren(sourceAttributeValue()); SVGElement::finishParsingChildren(); // A SVGLoad event has been fired by SVGElement::finishParsingChildren. @@ -212,11 +211,16 @@ bool SVGScriptElement::deferAttributeValue() const return false; } +bool SVGScriptElement::hasSourceAttribute() const +{ + return hasAttribute(XLinkNames::hrefAttr); +} + void SVGScriptElement::dispatchLoadEvent() { bool externalResourcesRequired = externalResourcesRequiredBaseValue(); - if (wasInsertedByParser()) + if (isParserInserted()) ASSERT(externalResourcesRequired != haveFiredLoadEvent()); else if (haveFiredLoadEvent()) { // If we've already fired an load event and externalResourcesRequired is set to 'true' @@ -247,7 +251,7 @@ void SVGScriptElement::dispatchErrorEvent() PassRefPtr<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren() const { - return adoptRef(new SVGScriptElement(tagQName(), document(), false, wasAlreadyStarted())); + return adoptRef(new SVGScriptElement(tagQName(), document(), false, alreadyStarted())); } } diff --git a/Source/WebCore/svg/SVGScriptElement.h b/Source/WebCore/svg/SVGScriptElement.h index dabec79..03cc733 100644 --- a/Source/WebCore/svg/SVGScriptElement.h +++ b/Source/WebCore/svg/SVGScriptElement.h @@ -42,7 +42,7 @@ public: void setType(const String&); private: - SVGScriptElement(const QualifiedName&, Document*, bool wasInsertedByParser, bool wasAlreadyStarted); + SVGScriptElement(const QualifiedName&, Document*, bool wasInsertedByParser, bool alreadyStarted); virtual void parseMappedAttribute(Attribute*); virtual void insertedIntoDocument(); @@ -68,6 +68,7 @@ private: virtual String eventAttributeValue() const; virtual bool asyncAttributeValue() const; virtual bool deferAttributeValue() const; + virtual bool hasSourceAttribute() const; virtual void dispatchLoadEvent(); virtual void dispatchErrorEvent(); diff --git a/Source/WebCore/svg/SVGStyledElement.cpp b/Source/WebCore/svg/SVGStyledElement.cpp index 7f3b041..5740b05 100644 --- a/Source/WebCore/svg/SVGStyledElement.cpp +++ b/Source/WebCore/svg/SVGStyledElement.cpp @@ -273,6 +273,11 @@ AnimatedAttributeType SVGStyledElement::animatedPropertyTypeForCSSProperty(const return AnimatedUnknown; } +bool SVGStyledElement::isAnimatableCSSProperty(const QualifiedName& attrName) +{ + return cssPropertyToTypeMap().contains(attrName); +} + void SVGStyledElement::fillPassedAttributeToPropertyTypeMap(AttributeToPropertyTypeMap& attributeToPropertyTypeMap) { attributeToPropertyTypeMap.set(HTMLNames::classAttr, AnimatedString); diff --git a/Source/WebCore/svg/SVGStyledElement.h b/Source/WebCore/svg/SVGStyledElement.h index 85a2b5a..b6c0b96 100644 --- a/Source/WebCore/svg/SVGStyledElement.h +++ b/Source/WebCore/svg/SVGStyledElement.h @@ -53,6 +53,7 @@ public: void setInstanceUpdatesBlocked(bool); AnimatedAttributeType animatedPropertyTypeForCSSProperty(const QualifiedName&); + static bool isAnimatableCSSProperty(const QualifiedName&); virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const; diff --git a/Source/WebCore/svg/SVGStyledTransformableElement.cpp b/Source/WebCore/svg/SVGStyledTransformableElement.cpp index ce1c5fd..1e32f9a 100644 --- a/Source/WebCore/svg/SVGStyledTransformableElement.cpp +++ b/Source/WebCore/svg/SVGStyledTransformableElement.cpp @@ -26,6 +26,7 @@ #include "AffineTransform.h" #include "Attribute.h" #include "RenderSVGPath.h" +#include "RenderSVGResource.h" #include "SVGNames.h" namespace WebCore { @@ -80,6 +81,21 @@ void SVGStyledTransformableElement::parseMappedAttribute(Attribute* attr) SVGStyledLocatableElement::parseMappedAttribute(attr); } +void SVGStyledTransformableElement::svgAttributeChanged(const QualifiedName& attrName) +{ + SVGStyledLocatableElement::svgAttributeChanged(attrName); + + if (!SVGStyledTransformableElement::isKnownAttribute(attrName)) + return; + + RenderObject* object = renderer(); + if (!object) + return; + + object->setNeedsTransformUpdate(); + RenderSVGResource::markForLayoutAndParentResourceInvalidation(object); +} + void SVGStyledTransformableElement::synchronizeProperty(const QualifiedName& attrName) { SVGStyledLocatableElement::synchronizeProperty(attrName); diff --git a/Source/WebCore/svg/SVGStyledTransformableElement.h b/Source/WebCore/svg/SVGStyledTransformableElement.h index cbd70ed..9d6834a 100644 --- a/Source/WebCore/svg/SVGStyledTransformableElement.h +++ b/Source/WebCore/svg/SVGStyledTransformableElement.h @@ -58,6 +58,7 @@ protected: SVGStyledTransformableElement(const QualifiedName&, Document*); virtual void parseMappedAttribute(Attribute*); + virtual void svgAttributeChanged(const QualifiedName&); virtual void synchronizeProperty(const QualifiedName&); void fillPassedAttributeToPropertyTypeMap(AttributeToPropertyTypeMap&); diff --git a/Source/WebCore/svg/SVGTextContentElement.cpp b/Source/WebCore/svg/SVGTextContentElement.cpp index 0bb8b3b..a719c28 100644 --- a/Source/WebCore/svg/SVGTextContentElement.cpp +++ b/Source/WebCore/svg/SVGTextContentElement.cpp @@ -145,7 +145,7 @@ void SVGTextContentElement::selectSubString(unsigned charnum, unsigned nchars, E return; // Find selection start - VisiblePosition start(const_cast<SVGTextContentElement*>(this), 0, SEL_DEFAULT_AFFINITY); + VisiblePosition start(firstPositionInNode(const_cast<SVGTextContentElement*>(this))); for (unsigned i = 0; i < charnum; ++i) start = start.next(); diff --git a/Source/WebCore/svg/SVGTransformable.cpp b/Source/WebCore/svg/SVGTransformable.cpp index e637e7c..a3107d1 100644 --- a/Source/WebCore/svg/SVGTransformable.cpp +++ b/Source/WebCore/svg/SVGTransformable.cpp @@ -89,6 +89,11 @@ 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}; +// This destructor is needed in order to link correctly with Intel ICC. +SVGTransformable::~SVGTransformable() +{ +} + bool SVGTransformable::parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform& transform) { if (type == SVGTransform::SVG_TRANSFORM_UNKNOWN) diff --git a/Source/WebCore/svg/SVGTransformable.h b/Source/WebCore/svg/SVGTransformable.h index 1cd2881..c713366 100644 --- a/Source/WebCore/svg/SVGTransformable.h +++ b/Source/WebCore/svg/SVGTransformable.h @@ -40,6 +40,8 @@ public: DoNotClearList }; + virtual ~SVGTransformable(); + 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&); diff --git a/Source/WebCore/svg/SVGUseElement.cpp b/Source/WebCore/svg/SVGUseElement.cpp index cc53bda..4239f66 100644 --- a/Source/WebCore/svg/SVGUseElement.cpp +++ b/Source/WebCore/svg/SVGUseElement.cpp @@ -185,12 +185,6 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) return; } - if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { - object->setNeedsTransformUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(object); - return; - } - if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) invalidateShadowTree(); @@ -242,7 +236,7 @@ void SVGUseElement::fillAttributeToPropertyTypeMap() attributeToPropertyTypeMap.set(SVGNames::yAttr, AnimatedLength); attributeToPropertyTypeMap.set(SVGNames::widthAttr, AnimatedLength); attributeToPropertyTypeMap.set(SVGNames::heightAttr, AnimatedLength); - attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedLength); + attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedString); } static void updateContainerSize(SVGUseElement* useElement, SVGElementInstance* targetInstance) diff --git a/Source/WebCore/svg/SVGVKernElement.cpp b/Source/WebCore/svg/SVGVKernElement.cpp index eed13d2..498a28f 100644 --- a/Source/WebCore/svg/SVGVKernElement.cpp +++ b/Source/WebCore/svg/SVGVKernElement.cpp @@ -50,6 +50,7 @@ void SVGVKernElement::insertedIntoDocument() if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode)) element->invalidateGlyphCache(); } + SVGElement::insertedIntoDocument(); } void SVGVKernElement::removedFromDocument() @@ -59,6 +60,7 @@ void SVGVKernElement::removedFromDocument() if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode)) element->invalidateGlyphCache(); } + SVGElement::removedFromDocument(); } void SVGVKernElement::buildVerticalKerningPair(KerningPairVector& kerningPairs) diff --git a/Source/WebCore/svg/animation/SMILTimeContainer.cpp b/Source/WebCore/svg/animation/SMILTimeContainer.cpp index 3251d5b..0bacdb3 100644 --- a/Source/WebCore/svg/animation/SMILTimeContainer.cpp +++ b/Source/WebCore/svg/animation/SMILTimeContainer.cpp @@ -196,15 +196,15 @@ String SMILTimeContainer::baseValueFor(ElementAttributePair key) if (it != m_savedBaseValues.end()) return it->second; - SVGElement* target = key.first; - String attributeName = key.second; - ASSERT(target); - ASSERT(!attributeName.isEmpty()); + SVGElement* targetElement = key.first; + QualifiedName attributeName = key.second; + ASSERT(targetElement); + ASSERT(attributeName != anyQName()); String baseValue; - if (SVGAnimationElement::attributeIsCSS(attributeName)) - baseValue = computedStyle(target)->getPropertyValue(cssPropertyID(attributeName)); + if (SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName)) + baseValue = computedStyle(targetElement)->getPropertyValue(cssPropertyID(attributeName.localName())); else - baseValue = target->getAttribute(attributeName); + baseValue = targetElement->getAttribute(attributeName); m_savedBaseValues.add(key, baseValue); return baseValue; } @@ -264,10 +264,11 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed) SVGElement* targetElement = animation->targetElement(); if (!targetElement) continue; - String attributeName = animation->attributeName(); - if (attributeName.isEmpty()) { + + QualifiedName attributeName = animation->attributeName(); + if (attributeName == anyQName()) { if (animation->hasTagName(SVGNames::animateMotionTag)) - attributeName = SVGNames::animateMotionTag.localName(); + attributeName = SVGNames::animateMotionTag; else continue; } @@ -276,6 +277,8 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed) ElementAttributePair key(targetElement, attributeName); SVGSMILElement* resultElement = resultsElements.get(key).get(); if (!resultElement) { + if (!animation->hasValidAttributeType()) + continue; resultElement = animation; resultElement->resetToBaseValue(baseValueFor(key)); resultsElements.add(key, resultElement); diff --git a/Source/WebCore/svg/animation/SMILTimeContainer.h b/Source/WebCore/svg/animation/SMILTimeContainer.h index bf734d3..2b46ff3 100644 --- a/Source/WebCore/svg/animation/SMILTimeContainer.h +++ b/Source/WebCore/svg/animation/SMILTimeContainer.h @@ -28,6 +28,7 @@ #if ENABLE(SVG) +#include "QualifiedName.h" #include "PlatformString.h" #include "SMILTime.h" #include "Timer.h" @@ -74,7 +75,7 @@ private: void updateDocumentOrderIndexes(); void sortByPriority(Vector<SVGSMILElement*>& smilElements, SMILTime elapsed); - typedef pair<SVGElement*, String> ElementAttributePair; + typedef pair<SVGElement*, QualifiedName> ElementAttributePair; String baseValueFor(ElementAttributePair); double m_beginTime; diff --git a/Source/WebCore/svg/animation/SVGSMILElement.cpp b/Source/WebCore/svg/animation/SVGSMILElement.cpp index 2364c6a..3bb5880 100644 --- a/Source/WebCore/svg/animation/SVGSMILElement.cpp +++ b/Source/WebCore/svg/animation/SVGSMILElement.cpp @@ -37,12 +37,12 @@ #include "FrameView.h" #include "HTMLNames.h" #include "SMILTimeContainer.h" +#include "SVGDocumentExtensions.h" #include "SVGNames.h" #include "SVGParserUtilities.h" #include "SVGSVGElement.h" #include "SVGURIReference.h" #include "XLinkNames.h" -#include <math.h> #include <wtf/MathExtras.h> #include <wtf/StdLibExtras.h> #include <wtf/Vector.h> @@ -115,6 +115,8 @@ SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const Str SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) + , m_attributeName(anyQName()) + , m_targetElement(0) , m_conditionsConnected(false) , m_hasEndEventConditions(false) , m_intervalBegin(SMILTime::unresolved()) @@ -140,6 +142,28 @@ SVGSMILElement::~SVGSMILElement() if (m_timeContainer) m_timeContainer->unschedule(this); } + +static inline QualifiedName constructQualifiedName(const SVGElement* svgElement, const String& attributeName) +{ + ASSERT(svgElement); + if (attributeName.isEmpty()) + return anyQName(); + if (!attributeName.contains(':')) + return QualifiedName(nullAtom, attributeName, nullAtom); + + String prefix; + String localName; + ExceptionCode ec = 0; + if (!Document::parseQualifiedName(attributeName, prefix, localName, ec)) + return anyQName(); + ASSERT(!ec); + + String namespaceURI = svgElement->lookupNamespaceURI(prefix); + if (namespaceURI.isEmpty()) + return anyQName(); + + return QualifiedName(nullAtom, localName, namespaceURI); +} void SVGSMILElement::insertedIntoDocument() { @@ -149,6 +173,7 @@ void SVGSMILElement::insertedIntoDocument() for (ContainerNode* n = this; n; n = n->parentNode()) ASSERT(!n->isShadowRoot()); #endif + m_attributeName = constructQualifiedName(this, getAttribute(SVGNames::attributeNameAttr)); SVGSVGElement* owner = ownerSVGElement(); if (!owner) return; @@ -160,10 +185,15 @@ void SVGSMILElement::insertedIntoDocument() void SVGSMILElement::removedFromDocument() { + m_attributeName = anyQName(); if (m_timeContainer) { m_timeContainer->unschedule(this); m_timeContainer = 0; } + if (m_targetElement) { + document()->accessSVGExtensions()->removeAnimationElementFromTarget(this, m_targetElement); + m_targetElement = 0; + } // Calling disconnectConditions() may kill us if there are syncbase conditions. // OK, but we don't want to die inside the call. RefPtr<SVGSMILElement> keepAlive(this); @@ -380,7 +410,11 @@ void SVGSMILElement::attributeChanged(Attribute* attr, bool preserveDecls) m_cachedMin = invalidCachedTime; else if (attrName == SVGNames::maxAttr) m_cachedMax = invalidCachedTime; - + else if (attrName == SVGNames::attributeNameAttr) { + if (inDocument()) + m_attributeName = constructQualifiedName(this, attr->value()); + } + if (inDocument()) { if (attrName == SVGNames::beginAttr) beginListChanged(); @@ -461,18 +495,19 @@ void SVGSMILElement::reschedule() SVGElement* SVGSMILElement::targetElement() const { + if (m_targetElement) + return m_targetElement; + String href = xlinkHref(); ContainerNode* target = href.isEmpty() ? parentNode() : document()->getElementById(SVGURIReference::getTarget(href)); - if (target && target->isSVGElement()) - return static_cast<SVGElement*>(target); - return 0; -} + if (!target || !target->isSVGElement()) + return 0; -String SVGSMILElement::attributeName() const -{ - return getAttribute(SVGNames::attributeNameAttr).string().stripWhiteSpace(); + m_targetElement = static_cast<SVGElement*>(target); + document()->accessSVGExtensions()->addAnimationElementToTarget(const_cast<SVGSMILElement*>(this), m_targetElement); + return m_targetElement; } - + SMILTime SVGSMILElement::elapsed() const { return m_timeContainer ? m_timeContainer->elapsed() : 0; diff --git a/Source/WebCore/svg/animation/SVGSMILElement.h b/Source/WebCore/svg/animation/SVGSMILElement.h index 2135642..0f26f26 100644 --- a/Source/WebCore/svg/animation/SVGSMILElement.h +++ b/Source/WebCore/svg/animation/SVGSMILElement.h @@ -49,11 +49,14 @@ public: virtual void insertedIntoDocument(); virtual void removedFromDocument(); virtual void finishParsingChildren(); + + virtual bool hasValidAttributeType() const = 0; SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); } SVGElement* targetElement() const; - String attributeName() const; + void resetTargetElement() { m_targetElement = 0; } + const QualifiedName& attributeName() const { return m_attributeName; } void beginByLinkActivation(); @@ -175,10 +178,14 @@ private: Frozen }; + QualifiedName m_attributeName; + ActiveState determineActiveState(SMILTime elapsed) const; float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const; SMILTime calculateNextProgressTime(SMILTime elapsed) const; + mutable SVGElement* m_targetElement; + Vector<Condition> m_conditions; bool m_conditionsConnected; bool m_hasEndEventConditions; diff --git a/Source/WebCore/svg/graphics/SVGImage.cpp b/Source/WebCore/svg/graphics/SVGImage.cpp index 2d400a4..85c00f3 100644 --- a/Source/WebCore/svg/graphics/SVGImage.cpp +++ b/Source/WebCore/svg/graphics/SVGImage.cpp @@ -263,8 +263,11 @@ bool SVGImage::dataChanged(bool allDataReceived) #endif // FIXME: If this SVG ends up loading itself, we might leak the world. - // The comment said that the Cache code does not know about CachedImages - // holding Frames and won't know to break the cycle. But + // The Cache code does not know about CachedImages holding Frames and + // won't know to break the cycle. + // This will become an issue when SVGImage will be able to load other + // SVGImage objects, but we're safe now, because SVGImage can only be + // loaded by a top-level document. m_page.set(new Page(pageClients)); m_page->settings()->setMediaEnabled(false); m_page->settings()->setJavaScriptEnabled(false); @@ -273,12 +276,9 @@ bool SVGImage::dataChanged(bool allDataReceived) RefPtr<Frame> frame = Frame::create(m_page.get(), 0, dummyFrameLoaderClient); frame->setView(FrameView::create(frame.get())); frame->init(); - ResourceRequest fakeRequest(KURL(ParsedURLString, "")); FrameLoader* loader = frame->loader(); loader->setForcedSandboxFlags(SandboxAll); - loader->load(fakeRequest, false); // Make sure the DocumentLoader is created - loader->policyChecker()->cancelCheck(); // cancel any policy checks - loader->commitProvisionalLoad(); + ASSERT(loader->activeDocumentLoader()); // DocumentLoader should have been created by frame->init(). loader->activeDocumentLoader()->writer()->setMIMEType("image/svg+xml"); loader->activeDocumentLoader()->writer()->begin(KURL()); // create the empty document loader->activeDocumentLoader()->writer()->addData(data()->data(), data()->size()); |