Closed Bug 873106 Opened 12 years ago Closed 12 years ago

SVG getCTM not including top most SVG element

Categories

(Core :: SVG, defect)

x86_64
Windows 7
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: helloworld922, Unassigned)

References

Details

User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31 Steps to reproduce: <svg id='svg_root' width='256' height='256' viewbox='0 0 512 512'> <rect id='elem' x='0' y='0' width='256' height='256'></rect> </svg> <script> var svg_root = document.getElementById('svg_root'); var elem = document.getElementById('elem'); var matrix = elem.getCTM(); </script> Actual results: matrix is not including the transformations from svg_root's user coordinate system (UCS) to its viewport coordinate system (VCS). Thus, matrix = identity Expected results: This is related to bug #543965, where it was deemed undefined behavior to call getCtM() on the outer SVG element, and thus Firefox returns null. According to http://www.w3.org/TR/SVG/coords.html#NestedTransformations: For each given element, the accumulation of all transformations that have been defined on the given element and all of its ancestors up to and including the element that established the current viewport (usually, the ‘svg’ element which is the most immediate ancestor to the given element) is called the current transformation matrix or CTM. The CTM thus represents the mapping of current user coordinates to viewport coordinates. My interpretation is that the VCS is the coordinate system for the "viewable area", with bounds (0, 0, width, height). The UCS should map to the viewBox + any transforms if specified, or default to the viewable area. This is not currently the case. getCTM() is not mapping to the outer SVG element's VCS, but is mapping to the UCS for the outer SVG element. Thus in the above test code, the correct value of matrix should be: 0.5 0 0 0 0.5 0 0 0 1 This is the primary reason why I think getCTM() for the outer SVG element should return a valid transformation matrix (as originally pointed out in bug #543965), because it does intrinsically have it's own UCS and VCS. Technically, while the outer SVG element must return null for the nearestViewportElement(), I still think that it should map a valid CTM because it does by definition establish its current viewport from the its user space, and indeed all my tests with Opera, Chrome, and IE10 show that this is what they do. I have not tested if nested SVG elements also improperly map to their respective UCS or VCS coordinates.
See Also: → 543965
Ahh, I see. What about the case of trying to get the CTM of a the outer svg element? Currently Firefox implements it to return null, while every other browser I've tried returns a valid CTM from user space to viewport space. I know in the past that it was determined to be undefined behavior (bug #543965), but reading that text it seems to me that this behavior should be defined. Specifically this part: For each given element, the accumulation of all transformations that have been defined ON THE GIVEN element and all of its ancestors up to and INCLUDING the element that established the current viewport By definition, the outer svg element is the given element, and it also establishes its current viewport. Perhaps it would be more appropriate to re-open bug #543965? I read through the comments on bug #543965 and they seem to be directed such that getCTM() might be implemented using some unclear method by getting offsets from the containing element of the outer SVG, but I think this isn't the correct interpretation of the specs. My interpretation is that getCTM() for the outer svg element should return the transformation resulting from the viewBox and transform attributes of the outer svg element (if present), otherwise default to the identity transform because the user space = viewport space.
To expand on bug 543965 comment 9 nearestViewportElement The element which established the current viewport. Often, the nearest ancestor ‘svg’ element. Null if the current element is the outermost svg element. So the nearestViewportElement is null SVGMatrix getCTM() Returns the transformation matrix from current user units (i.e., after application of the ‘transform’ attribute, if any) to the viewport coordinate system for the nearestViewportElement. So we need to return the transformation matrix to the viewport coordinate system for something which is null
Hmm... The technical definition is that the CTM must include the transform of the element itself, and any elements up to and including the element which establishes the current viewport. In Firefox's implementation, the element which establishes the current viewport is always the result of nearestViewportElement(), which is null for the outer svg element, which means the CTM is undefined and null is as good or better than any other CTM returned. However, I don't think the element which establishes the outer svg's current viewport is null, because null cannot establish the current viewport. The outer svg element establishes it's own viewport by using the SVG user agent to negotiate with the parent user agent, so the set of elements which CTM(outer_svg) must operate on is just the outer svg element. This does have a valid transform, which goes from the outer svg element's user space to its viewport space. The ambiguity is that getCTM()'s definition implies Firefox's implementation is correct, but it doesn't necessarily return the technical definition of the CTM as its name would imply. This means it is impossible (or rather difficult/convoluted) to get the transformation matrix from the svg outer's user space to its viewport space. I think this would be a good point to bring up to the standards committee for resolution.
Go for it. Here's how you contact the SVG Specification writers: http://lists.w3.org/Archives/Public/www-svg/
I posted a message on the SVG mailing list: http://lists.w3.org/Archives/Public/www-svg/2013May/0047.html
BTW doesn't calling getScreenCTM work for your use case?
Not directly, getScreenCTM includes transforms external to the outer SVG element. For example: <p>This is some filler stuff</p> <svg id='outer_svg' width='16' height='16'> </svg> <script> var outer_svg = document.getElementById('outer_svg'); var point = outer_svg.createSVGPoint(); var loc = point.matrixTransform(outer_svg.getScreenCTM()); </script> This could have loc equal any point (x,y) depending on what other elements are around the SVG, the stylesheet, user scrolling/zoom level, etc. while using the true CTM would always have loc=point.
You need to log in before you can comment on or make changes to this bug.