Index: Source/core/svg/SVGElement.cpp |
diff --git a/Source/core/svg/SVGElement.cpp b/Source/core/svg/SVGElement.cpp |
index b051e1370a0efd813e68648ca7c7e50a9d753230..c6537d2c5e65533a00c7a2f090d9762c91d63888 100644 |
--- a/Source/core/svg/SVGElement.cpp |
+++ b/Source/core/svg/SVGElement.cpp |
@@ -1191,4 +1191,36 @@ const AtomicString& SVGElement::eventParameterName() |
return evtString; |
} |
+bool SVGElement::getStyleTransform(AffineTransform& matrix) const |
+{ |
+ RenderStyle* style = renderer() ? renderer()->style() : 0; |
+ if (style && style->hasTransform()) { |
+ TransformationMatrix transform; |
+ float zoom = style->effectiveZoom(); |
+ |
+ // 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 = renderer()->objectBoundingBox(); |
+ scaledBBox.scale(zoom); |
+ transform.scale(1 / zoom); |
+ style->applyTransform(transform, scaledBBox); |
+ transform.scale(zoom); |
+ } else { |
+ style->applyTransform(transform, renderer()->objectBoundingBox()); |
+ } |
+ |
+ // Flatten any 3D transform. |
+ matrix = transform.toAffineTransform(); |
+ return true; |
+ } |
+ return false; |
+} |
+ |
} |