Index: Source/core/svg/SVGGraphicsElement.cpp |
diff --git a/Source/core/svg/SVGGraphicsElement.cpp b/Source/core/svg/SVGGraphicsElement.cpp |
index 2d9afe58cf15a9d9d2161aaa3aee1f4c37983967..b1d99aa6b7e8c695a676e800e92a9f5e54bb783d 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, SVGGraphicsElement::StyleUpdateStrategy styleUpdateStrategy) |
pdr.
2013/11/08 23:50:48
There's no need to specify "SVGGraphicsElement::St
rwlbuis
2013/11/10 20:35:45
Done.
|
+{ |
+ 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,42 @@ void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName) |
SVGElement* SVGGraphicsElement::nearestViewportElement() const |
{ |
- return SVGTransformable::nearestViewportElement(this); |
+ return nearestViewportElement(this); |
} |
SVGElement* SVGGraphicsElement::farthestViewportElement() const |
{ |
- return SVGTransformable::farthestViewportElement(this); |
+ return farthestViewportElement(this); |
+} |
+ |
+static bool isViewportElement(Node* node) |
+{ |
+ return (node->hasTagName(SVGNames::svgTag) |
+ || node->hasTagName(SVGNames::symbolTag) |
+ || node->hasTagName(SVGNames::foreignObjectTag) |
+ || node->hasTagName(SVGNames::imageTag)); |
pdr.
2013/11/08 23:50:48
This was probably a latent bug. Images don't have
rwlbuis
2013/11/10 20:35:45
I am not sure, this list is stated here:
http://w
pdr.
2013/11/11 00:02:09
Ah, you are correct. It looks like viewports and v
|
+} |
+ |
+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; |
+} |
+ |
+SVGElement* SVGGraphicsElement::farthestViewportElement(const SVGElement* element) |
+{ |
+ ASSERT(element); |
+ SVGElement* farthest = 0; |
+ for (Element* current = element->parentOrShadowHostElement(); current; current = current->parentOrShadowHostElement()) { |
+ if (isViewportElement(current)) |
+ farthest = toSVGElement(current); |
+ } |
+ return farthest; |
} |
SVGRect SVGGraphicsElement::getBBox() |