Open Bug 836768 Opened 11 years ago Updated 2 years ago

SVG path hit detection is sometimes inaccurate (low precision) under extreme scaling

Categories

(Core :: SVG, defect)

17 Branch
defect

Tracking

()

People

(Reporter: anwa, Unassigned)

References

Details

(Keywords: regression, testcase)

Attachments

(1 file)

Attached file svg-bug.html
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20130131 Firefox/21.0
Build ID: 20130131031009

Steps to reproduce:

Firefox versions/platforms: 
Windows 7 / Firefox 18
Ubuntu / Firefox 18
Windows 7 / Nightly 21.0a1 (Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20130131 Firefox/21.0)
Windows 7 / Firefox ESR 10.0.0.12 is *not* affected.

- Create an SVG stage using a viewBox with high magnification/zoom (e.g. a 1000x1000 pixel SVG with viewBox="0,0,1,1")
- Create a path with a large bounding box (e.g. 1000x1000)
- Nest the path within a <g> element with a transform which scales the path to the 0..1 coordinate system (e.g. transform="matrix(0.001, 0, 0, 0.001, 0, 0)" )
- Nest the path within a <g> element with no attributes
- Attempt to render the SVG (e.g. by embedding it in an HTML5 document)


Actual results:

The SVG will not respond to mouse events reliably: sometimes clicking within the path results in a click on the element behind the path. Scanning pixel-by-pixel across the path and using document.elementFromPoint() to hit test reveals that the path's hit envelope is extremely inaccurate, as if pixelated at a low resolution. With a complex path (e.g. a human figure) this means that some segments of the path (e.g. arms) are almost impossible to click on.

The shape of the hit envelope is independent of the pixel size of the final SVG stage, but it does vary with the degree of scaling: using a viewBox of 0,0,100,100 and only scaling the path down by a factor of 10 instead of 1000 mostly eliminates the problem. Removing the viewBox and transform also eliminates the problem.

Interestingly, the problem is also fixed if the outer g element (the one with no attributes) is removed. Since this element has no transform, it theoretically shouldn't affect the rendering at all.

The attached file demonstrates a) the problem, and b) the problem 'fixed' by removing the outer group element.


Expected results:

Regardless of magnification, the hit envelope of a path should be accurate to the pixel level: clicks within the path should always result in a click event firing on the path, and clicks outside the path should result in clicks on the element behind the path.
Attachment #708597 - Attachment mime type: text/plain → text/html
Summary: SVG hit detection is sometimes inaccurate (low precision) under extreme scaling → SVG path hit detection is sometimes inaccurate (low precision) under extreme scaling
Andy, would you be willing to a regression range?

Just follow the instructions at http://mozilla.github.com/mozregression/
Regression range:

m-c
good=2012-08-02
bad=2012-08-03
http://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=588424024294&tochange=89dcadd42ec4

Suspected bug:
Jonathan Watt — Bug 776054 - Flip the prefs to enable the use of display lists for SVG painting and hit-testing. r=roc.

Workaround:
svg.display-lists.painting.enabled = false
svg.display-lists.hit-testing.enabled = false
fixes the issue.
Blocks: 776054
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: regression, testcase
OS: Windows 7 → All
Hardware: x86_64 → All
Version: 21 Branch → 17 Branch
We have this...

      <svg viewBox='0,0.175,0.2,0.2' width=191 height=540>
        <g id="causerOfBug">
          <g id="layer1" transform="matrix(0.000430474572993606, 0, 0, 0.000430474572993606, 0, 0)"> 

nsDisplayTransform::HitTest operates at different scales depending on whether the <g> is present or not as the viewBox and layer1 transforms cancel out in nsDisplayTransform::GetResultingTransformMatrix if they are direct parent/child.

Without the cancelling we round to "appUnits" which aren't really appUnits as we go through the displayList.

nsDisplayTransform::HitTest seems to be where the rounding occurs with its NSFloatPixelsToAppUnits calls.

Any ideas Jonathan?
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: