WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 44083
SVGLocatable.getScreenCTM ignores scrolling
https://bugs.webkit.org/show_bug.cgi?id=44083
Summary
SVGLocatable.getScreenCTM ignores scrolling
Mike Bostock
Reported
2010-08-16 18:07:33 PDT
Created
attachment 64541
[details]
Test case. Per SVG Tiny 1.2, Section A.8.11 SVGLocatable: """ getScreenCTM Returns the transformation matrix from current user units to the initial viewport coordinate system. The clientX and clientY coordinates of a MouseEvent are in the initial viewport coordinate system. Note that null is returned if this element is not hooked into the document tree. This method would have been more aptly named as getClientCTM, but the name getScreenCTM is kept for historical reasons. """ In WebKit (and Safari, Chrome), the matrix returned by getScreenCTM considers the scrollTop and scrollLeft. Therefore, it is as if pageX and pageY were used instead of clientX and clientY, as described by the spec. Firefox and Opera exhibit the correct behavior, consistent with clientX and clientY.
Attachments
Test case.
(1.85 KB, text/html)
2010-08-16 18:07 PDT
,
Mike Bostock
no flags
Details
Expected output of test case.
(11.36 KB, image/png)
2010-08-16 18:08 PDT
,
Mike Bostock
no flags
Details
Actual output of test case.
(12.22 KB, image/png)
2010-08-16 18:09 PDT
,
Mike Bostock
no flags
Details
Patch
(119.38 KB, patch)
2010-08-27 00:55 PDT
,
Nikolas Zimmermann
krit
: review+
Details
Formatted Diff
Diff
Test case for getScreenCTM and scrolling on iOS.
(1.90 KB, text/html)
2014-06-27 09:06 PDT
,
Jason Davies
no flags
Details
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Mike Bostock
Comment 1
2010-08-16 18:08:52 PDT
Created
attachment 64542
[details]
Expected output of test case.
Mike Bostock
Comment 2
2010-08-16 18:09:15 PDT
Created
attachment 64543
[details]
Actual output of test case.
Mike Bostock
Comment 3
2010-08-16 18:21:32 PDT
Oops, clarification to my initial description: getScreenCTM ignores scrollTop and scrollLeft in WebKit, which is why it is inconsistent with clientX and clientY. For example, in Firefox and Opera, if you scroll down by 200 pixels, svg.getScreenCTM().f will go down by 200 pixels (e.g., 92 -> -108). On the other hand, in WebKit, Safari and Chrome the value of svg.getScreenCTM().f will stay constant independent of scrolling.
Eric Seidel (no email)
Comment 4
2010-08-24 21:39:15 PDT
http://trac.webkit.org/browser/trunk/WebCore/svg/SVGLocatable.cpp#L87
is the code. Notice how it stops at the first non-SVG element. I suspect that scrolling may be expressed in tx/ty anyway, I'm not sure.
Mike Bostock
Comment 5
2010-08-24 23:42:55 PDT
(In reply to
comment #4
)
> Notice how it stops at the first non-SVG element.
That's true for mode == NearestViewportScope (getCTM), but not mode == ScreenScope (getScreenCTM), where stopAtElement is 0 and it goes all the way to the root element. I think what's needed is something like this at the end of computeCTM: if (mode == ScreenScope) { DOMWindow* window = element->ownerDocument()->defaultView(); ctm = ctm.translate(window->scrollX(), window->scrollY()); } return ctm; Although I haven't thought through whether it should be translate or translateRight, yet. Or maybe -scrollX and -scrollY.
Mike Bostock
Comment 6
2010-08-24 23:44:07 PDT
(In reply to
comment #4
)
> Notice how it stops at the first non-SVG element.
Oops, right. I see the current->isSVGElement() now. Either way, that part looks fine. It's just not taking into account scrolling.
Eric Seidel (no email)
Comment 7
2010-08-24 23:55:54 PDT
Maybe the solution is as simple as asking frame()->view() for the scrollOffset().
Nikolas Zimmermann
Comment 8
2010-08-25 00:21:20 PDT
(In reply to
comment #0
)
> Created an attachment (id=64541) [details] > Test case. > > Per SVG Tiny 1.2, Section A.8.11 SVGLocatable: > > """ > getScreenCTM > > Returns the transformation matrix from current user units to the initial viewport coordinate system. The clientX and clientY coordinates of a MouseEvent are in the initial viewport coordinate system. Note that null is returned if this element is not hooked into the document tree. This method would have been more aptly named as getClientCTM, but the name getScreenCTM is kept for historical reasons. > """
First of all, we focus on SVG 1.1 2nd Edition, not SVG Tiny 1.2. I explicitely ignored the scroll offset when implementing these functions, because what SVG 1.1 says, is:
http://www.w3.org/TR/SVG/types.html#InterfaceSVGLocatable
Returns the transformation matrix from current user units (i.e., after application of the ‘transform’ attribute, if any) to the parent user agent's notice of a "pixel". For display devices, ideally this represents a physical screen pixel. For other devices or environments where physical pixel sizes are not known, then an algorithm similar to the CSS2 definition of a "pixel" can be used instead. Note that null is returned if this element is not hooked into the document tree. This method would have been more aptly named as getClientCTM, but the name getScreenCTM is kept for historical reasons. I was not sure about scrolling, but it seems to me that the SVG Tiny 1.2 behaviour is more clear. So, I'll have a look to fix it.
Simon Fraser (smfr)
Comment 9
2010-08-25 09:32:33 PDT
(In reply to
comment #7
)
> Maybe the solution is as simple as asking frame()->view() for the scrollOffset().
What about SVG nested inside multiple overflow:scroll divs?
Mike Bostock
Comment 10
2010-08-25 11:53:43 PDT
(In reply to
comment #9
)
> What about SVG nested inside multiple overflow:scroll divs?
That part's fine, as you can see from this test case:
http://graphics.stanford.edu/~mbostock/getScreenCTM-nested.html
The goal is for getScreenCTM to be consistent with the mouse event's clientX and clientY. The only discrepancy with the current implementation is scrolling on the parent frame or window; scrolled container elements appear to be handled correctly (and thus are consistent with pageX and pageY).
Nikolas Zimmermann
Comment 11
2010-08-27 00:55:57 PDT
Created
attachment 65686
[details]
Patch Indeed, all we need to do is respect the FrameViews scrollOffset. Nested divs with overflow="scroll" already work properly, as the localToAbsolute() call already takes care of handling those translations. Added three new tests covering scrollable SVG areas, and a large SVG area contained in (nested) divs with overflow="scroll", to rule out Simons concerncs.
Dirk Schulze
Comment 12
2010-08-27 01:05:29 PDT
Comment on
attachment 65686
[details]
Patch Great examples! r=me
Nikolas Zimmermann
Comment 13
2010-08-27 01:10:45 PDT
Landed in
r66187
. Mike, please retry, with a nightly newer or equa to
r66187
:-)
Mike Bostock
Comment 14
2010-08-31 23:45:20 PDT
(In reply to
comment #13
)
> Landed in
r66187
. Mike, please retry, with a nightly newer or equa to
r66187
:-)
Works great! Thanks for fixing this.
Jason Davies
Comment 15
2014-06-27 09:06:41 PDT
Created
attachment 233985
[details]
Test case for getScreenCTM and scrolling on iOS.
Jason Davies
Comment 16
2014-06-27 09:08:08 PDT
Unfortunately this issue seems to be unresolved on Safari in iOS 7.1.1. I’ve attached a modified version Mike’s test case that uses touchmove instead of mousemove.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug