| Index: third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp | 
| diff --git a/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp b/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp | 
| index 3a5da4ecef86c5f62415dea669813485efade5bd..ef6163ef7b2b9d0e1f6ad0e7b482d05612fe6a0b 100644 | 
| --- a/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp | 
| +++ b/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp | 
| @@ -22,7 +22,8 @@ | 
| #include "core/svg/SVGGraphicsElement.h" | 
|  | 
| #include "core/SVGNames.h" | 
| -#include "core/layout/svg/LayoutSVGPath.h" | 
| +#include "core/dom/StyleChangeReason.h" | 
| +#include "core/layout/LayoutObject.h" | 
| #include "core/svg/SVGElementRareData.h" | 
| #include "core/svg/SVGMatrixTearOff.h" | 
| #include "core/svg/SVGRectTearOff.h" | 
| @@ -35,8 +36,9 @@ SVGGraphicsElement::SVGGraphicsElement(const QualifiedName& tagName, | 
| ConstructionType constructionType) | 
| : SVGElement(tagName, document, constructionType), | 
| SVGTests(this), | 
| -      m_transform( | 
| -          SVGAnimatedTransformList::create(this, SVGNames::transformAttr)) { | 
| +      m_transform(SVGAnimatedTransformList::create(this, | 
| +                                                   SVGNames::transformAttr, | 
| +                                                   CSSPropertyTransform)) { | 
| addToPropertyMap(m_transform); | 
| } | 
|  | 
| @@ -108,75 +110,16 @@ SVGMatrixTearOff* SVGGraphicsElement::getScreenCTMFromJavascript() { | 
| return SVGMatrixTearOff::create(getScreenCTM()); | 
| } | 
|  | 
| -bool SVGGraphicsElement::hasAnimatedLocalTransform() const { | 
| -  const ComputedStyle* style = | 
| -      layoutObject() ? layoutObject()->style() : nullptr; | 
| - | 
| -  // Each of these is used in | 
| -  // SVGGraphicsElement::calculateAnimatedLocalTransform to create an animated | 
| -  // local transform. | 
| -  return (style && style->hasTransform()) || | 
| -         !m_transform->currentValue()->isEmpty() || hasSVGRareData(); | 
| -} | 
| - | 
| -AffineTransform SVGGraphicsElement::calculateAnimatedLocalTransform() const { | 
| -  AffineTransform matrix; | 
| -  const ComputedStyle* style = | 
| -      layoutObject() ? layoutObject()->style() : nullptr; | 
| - | 
| -  // If CSS property was set, use that, otherwise fallback to attribute (if | 
| -  // set). | 
| -  if (style && style->hasTransform()) { | 
| -    TransformationMatrix transform; | 
| -    float zoom = style->effectiveZoom(); | 
| - | 
| -    // SVGTextElements need special handling for the text positioning code. | 
| -    if (isSVGTextElement(this)) { | 
| -      // Do not take into account SVG's zoom rules, transform-origin, or | 
| -      // percentage values. | 
| -      style->applyTransform( | 
| -          transform, LayoutSize(0, 0), ComputedStyle::ExcludeTransformOrigin, | 
| -          ComputedStyle::IncludeMotionPath, | 
| -          ComputedStyle::IncludeIndependentTransformProperties); | 
| -    } else { | 
| -      // CSS transforms operate with pre-scaled lengths. To make this work with | 
| -      // SVG (which applies the zoom factor globally, at the root level) we | 
| -      // | 
| -      //   * pre-scale the bounding box (to bring it into the same space as the | 
| -      //     other CSS values) | 
| -      //   * invert the zoom factor (to effectively compute the CSS transform | 
| -      //     under a 1.0 zoom) | 
| -      // | 
| -      // Note: objectBoundingBox is an emptyRect for elements like pattern or | 
| -      // clipPath.  See the "Object bounding box units" section of | 
| -      // http://dev.w3.org/csswg/css3-transforms/ | 
| -      if (zoom != 1) { | 
| -        FloatRect scaledBBox = layoutObject()->objectBoundingBox(); | 
| -        scaledBBox.scale(zoom); | 
| -        transform.scale(1 / zoom); | 
| -        style->applyTransform( | 
| -            transform, scaledBBox, ComputedStyle::IncludeTransformOrigin, | 
| -            ComputedStyle::IncludeMotionPath, | 
| -            ComputedStyle::IncludeIndependentTransformProperties); | 
| -        transform.scale(zoom); | 
| -      } else { | 
| -        style->applyTransform( | 
| -            transform, layoutObject()->objectBoundingBox(), | 
| -            ComputedStyle::IncludeTransformOrigin, | 
| -            ComputedStyle::IncludeMotionPath, | 
| -            ComputedStyle::IncludeIndependentTransformProperties); | 
| -      } | 
| -    } | 
| - | 
| -    // Flatten any 3D transform. | 
| -    matrix = transform.toAffineTransform(); | 
| -  } else { | 
| -    m_transform->currentValue()->concatenate(matrix); | 
| +void SVGGraphicsElement::collectStyleForPresentationAttribute( | 
| +    const QualifiedName& name, | 
| +    const AtomicString& value, | 
| +    MutableStylePropertySet* style) { | 
| +  if (name == SVGNames::transformAttr) { | 
| +    addPropertyToPresentationAttributeStyle( | 
| +        style, CSSPropertyTransform, m_transform->currentValue()->cssValue()); | 
| +    return; | 
| } | 
| - | 
| -  if (hasSVGRareData()) | 
| -    return *svgRareData()->animateMotionTransform() * matrix; | 
| -  return matrix; | 
| +  SVGElement::collectStyleForPresentationAttribute(name, value, style); | 
| } | 
|  | 
| AffineTransform* SVGGraphicsElement::animateMotionTransform() { | 
| @@ -197,8 +140,15 @@ void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName) { | 
| if (!object) | 
| return; | 
|  | 
| +    invalidateSVGPresentationAttributeStyle(); | 
| + | 
| SVGElement::InvalidationGuard invalidationGuard(this); | 
| -    object->setNeedsTransformUpdate(); | 
| +    // TODO(fs): The InvalidationGuard will make sure all instances are | 
| +    // invalidated, but the style recalc will propagate to instances too. So | 
| +    // there is some redundant operations being performed here. Could we get | 
| +    // away with removing the InvalidationGuard? | 
| +    setNeedsStyleRecalc(LocalStyleChange, | 
| +                        StyleChangeReasonForTracing::fromAttribute(attrName)); | 
| markForLayoutAndParentResourceInvalidation(object); | 
| return; | 
| } | 
|  |