Chromium Code Reviews| 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() |