| Index: Source/core/svg/SVGGraphicsElement.cpp
|
| diff --git a/Source/core/svg/SVGGraphicsElement.cpp b/Source/core/svg/SVGGraphicsElement.cpp
|
| index 2d9afe58cf15a9d9d2161aaa3aee1f4c37983967..5b16efbcc1dbe91154a6626e3334d305ed10b82f 100644
|
| --- a/Source/core/svg/SVGGraphicsElement.cpp
|
| +++ b/Source/core/svg/SVGGraphicsElement.cpp
|
| @@ -50,14 +50,53 @@ SVGGraphicsElement::~SVGGraphicsElement()
|
| {
|
| }
|
|
|
| +AffineTransform SVGGraphicsElement::getTransformToElement(SVGElement* target, ExceptionState& es, StyleUpdateStrategy styleUpdateStrategy)
|
| +{
|
| + AffineTransform ctm = getCTM(styleUpdateStrategy);
|
| +
|
| + if (target && target->isSVGGraphicsElement()) {
|
| + AffineTransform targetCTM = toSVGGraphicsElement(target)->getCTM(styleUpdateStrategy);
|
| + if (!targetCTM.isInvertible()) {
|
| + es.throwUninformativeAndGenericDOMException(InvalidStateError);
|
| + return ctm;
|
| + }
|
| + ctm = targetCTM.inverse() * ctm;
|
| + }
|
| +
|
| + return ctm;
|
| +}
|
| +
|
| +static AffineTransform computeCTM(SVGElement* element, SVGElement::CTMScope mode, SVGGraphicsElement::StyleUpdateStrategy styleUpdateStrategy)
|
| +{
|
| + ASSERT(element);
|
| + if (styleUpdateStrategy == SVGGraphicsElement::AllowStyleUpdate)
|
| + element->document().updateLayoutIgnorePendingStylesheets();
|
| +
|
| + AffineTransform ctm;
|
| +
|
| + SVGElement* stopAtElement = mode == SVGGraphicsElement::NearestViewportScope ? SVGGraphicsElement::nearestViewportElement(element) : 0;
|
| + for (Element* currentElement = element; currentElement; currentElement = currentElement->parentOrShadowHostElement()) {
|
| + if (!currentElement->isSVGElement())
|
| + break;
|
| +
|
| + ctm = toSVGElement(currentElement)->localCoordinateSpaceTransform(mode).multiply(ctm);
|
| +
|
| + // For getCTM() computation, stop at the nearest viewport element
|
| + if (currentElement == stopAtElement)
|
| + break;
|
| + }
|
| +
|
| + return ctm;
|
| +}
|
| +
|
| AffineTransform SVGGraphicsElement::getCTM(StyleUpdateStrategy styleUpdateStrategy)
|
| {
|
| - return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy);
|
| + return computeCTM(this, NearestViewportScope, styleUpdateStrategy);
|
| }
|
|
|
| AffineTransform SVGGraphicsElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy)
|
| {
|
| - return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy);
|
| + return computeCTM(this, ScreenScope, styleUpdateStrategy);
|
| }
|
|
|
| AffineTransform SVGGraphicsElement::animatedLocalTransform() const
|
| @@ -158,12 +197,36 @@ void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName)
|
|
|
| SVGElement* SVGGraphicsElement::nearestViewportElement() const
|
| {
|
| - return SVGTransformable::nearestViewportElement(this);
|
| + return nearestViewportElement(this);
|
| +}
|
| +
|
| +static bool isViewportElement(Node* node)
|
| +{
|
| + return (node->hasTagName(SVGNames::svgTag)
|
| + || node->hasTagName(SVGNames::symbolTag)
|
| + || node->hasTagName(SVGNames::foreignObjectTag)
|
| + || node->hasTagName(SVGNames::imageTag));
|
| }
|
|
|
| SVGElement* SVGGraphicsElement::farthestViewportElement() const
|
| {
|
| - return SVGTransformable::farthestViewportElement(this);
|
| + SVGElement* farthest = 0;
|
| + for (Element* current = parentOrShadowHostElement(); current; current = current->parentOrShadowHostElement()) {
|
| + if (isViewportElement(current))
|
| + farthest = toSVGElement(current);
|
| + }
|
| + return farthest;
|
| +}
|
| +
|
| +SVGElement* SVGGraphicsElement::nearestViewportElement(const SVGElement* element)
|
| +{
|
| + ASSERT(element);
|
| + for (Element* current = element->parentOrShadowHostElement(); current; current = current->parentOrShadowHostElement()) {
|
| + if (isViewportElement(current))
|
| + return toSVGElement(current);
|
| + }
|
| +
|
| + return 0;
|
| }
|
|
|
| SVGRect SVGGraphicsElement::getBBox()
|
|
|