<canvas> isPointInPath doesn't transform its coordinates

VERIFIED FIXED in mozilla7

Status

()

Core
Canvas: 2D
VERIFIED FIXED
10 years ago
6 years ago

People

(Reporter: Ilmari Heikkinen, Assigned: Benjamin)

Tracking

(Blocks: 1 bug, {dev-doc-complete})

Trunk
mozilla7
x86
Linux
dev-doc-complete
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(Not tracked)

Details

(URL)

Attachments

(3 attachments, 1 obsolete attachment)

(Reporter)

Description

10 years ago
User-Agent:       Mozilla/5.0 (X11; U; Linux i686 (x86_64); fi; rv:1.9b1) Gecko/2007110903 Firefox/3.0b1
Build Identifier: Mozilla/5.0 (X11; U; Linux i686 (x86_64); fi; rv:1.9b1) Gecko/2007110903 Firefox/3.0b1

When using ctx.isPointInPath(x,y), the x,y-coords should be multiplied by the current transformation matrix to have isPointInPath work for transformed paths. 

The WhatWG spec[1] wording is a bit confusing on this matter: 
"The isPointInPath(x, y) method must return true if the point given by the x and y coordinates passed to the method, when treated as coordinates in the canvas' coordinate space unaffected by the current transformation..."

The idea being that the x,y-coordinates are in canvas space and hence must be transformed to the current space to do the isPointInPath-test.

[1] http://www.whatwg.org/specs/web-apps/current-work/multipage/section-the-canvas.html#ispointinpath

Reproducible: Always

Steps to Reproduce:
1. Change canvas transform (translate/rotate/scale.)
2. Use isPointInPath on a point that would have had its return value changed by the transform.

Actual Results:  
The return value didn't change.

Expected Results:  
The return value should've had changed.

Updated

10 years ago
Component: General → Layout: Canvas
Product: Firefox → Core
QA Contact: general → layout.canvas
Version: unspecified → Trunk
(Reporter)

Comment 1

10 years ago
Created attachment 290828 [details] [diff] [review]
Transform coords to device-space before cairo_in_fill-check

Comment 2

10 years ago
This bug is INVALID as far as I can tell.
(Reporter)

Comment 3

10 years ago
Opera handles isPointInPath coordinates as untransformed coordinates. See test in URL with Firefox vs. Opera. With setTransform, Firefox's behaviour can be worked around.

(Reporter)

Updated

10 years ago
Attachment #290828 - Flags: review?
(Reporter)

Updated

10 years ago
Attachment #290828 - Flags: review? → review?(vladimir)
(Reporter)

Comment 4

10 years ago
My original explanation of "how to fix" is wrong. The patch works, but the math is: multiply mouse coords by the inverse of the current transformation matrix.  Which the patch does implicitly (changing the matrix changes the path's matrix as well, so transforming the path to the point's matrix equals to transforming the point to the path's matrix.)

It can be worked around on a web page by using setTransform or by manually keeping track of the current transformation matrix and doing multiply(invert(matrix), [x,y,1]). Latter way + bbox / circle test can then be used to implement a crude version of isPointInPath for browsers that lack it.

Updated

10 years ago
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: blocking1.9?
WONTFIX'ing this as per bug 380338 -- paths don't get transformed, points do.  Changing the transformation matrix has no effect on the path that's currently built up.
Status: NEW → RESOLVED
Last Resolved: 10 years ago
Flags: blocking1.9?
Resolution: --- → WONTFIX
(Reporter)

Comment 6

10 years ago
Created attachment 295907 [details]
JS workaround to normalize isPointInPath behaviour across browsers

Note that you need to keep track of the current transformation matrix on Firefox 2. Implementation is left to the reader. Cheers!

Comment 7

10 years ago
Created attachment 312691 [details]
isPointInPath with transformations testcase

I don't understand why this still is a WONTFIX, but here is a simple testcase of isPointInPath with transformations, and a (very simple) workaround for Mozilla included.

Comment 8

10 years ago
(Sorry, the circles should highlight when you move your mouse over them in the testcase.)
Attachment #290828 - Flags: review?(vladimir)

Comment 9

7 years ago
Comment #5 is incorrect. Paths are transformed "IF" there transform is set before the path is drawn. The transform should not be applied retroactively as was being requested in the referenced bug.  As per the specification the isPointInPath method should test the query point "AS IS" again the "transformed" Path.

Please reopen this issue!

Comment 10

7 years ago
Please reopen this, all other modern browsers are implementing correctly and this functionality is critical to making canvas interactive (e.g. is my mouse inside this path after transforms have been applied). 

example

http://philip.html5.org/tests/canvas/suite/tests/index.2d.path.isPointInPath.html

tested on IE9, Chrome, Opera, Safari (iphone and ipad)

Comment 11

7 years ago
For those struggling with this, a "simple" workaround is to detect the bug, then replace isPointInPath() with a correct one (please excuse the poor formatting, just a copy/paste of old code):


var c2dp = CanvasRenderingContext2D.prototype;

//  special isPointInPath method to workaround Mozilla bug 405300
//      [https://bugzilla.mozilla.org/show_bug.cgi?id=405300]
function isPointInPath_mozilla( x, y )
{
    this.save();
    this.setTransform( 1, 0, 0, 1, 0, 0 );
    var ret = this.isPointInPath_old( x, y );
    this.restore();
    return ret;
};

//  test for the presence of the bug, and set the workaround function only if needed
var ctx = document.createElement( "canvas" ).getContext( "2d" );
ctx.translate( 50, 0 );
ctx.moveTo( 125, 50 );
ctx.arc( 100, 50, 25, 0, 360, false );
if( !ctx.isPointInPath( 150, 50 ) )
{
    c2dp.isPointInPath_old = c2dp.isPointInPath;
    c2dp.isPointInPath = isPointInPath_mozilla;
}
We should get either the spec or our implementation changed.
Blocks: 622842
Status: RESOLVED → REOPENED
Resolution: WONTFIX → ---

Updated

7 years ago
Duplicate of this bug: 589555
Relevant tests:

http://www.w3c-test.org/html/tests/approved/canvas/2d.path.isPointInPath.transform.1.html
http://www.w3c-test.org/html/tests/approved/canvas/2d.path.isPointInPath.transform.2.html
http://www.w3c-test.org/html/tests/approved/canvas/2d.path.isPointInPath.transform.3.html
http://samples.msdn.microsoft.com/ietestcenter/html5/canvas_harness.htm?url=canvas-complexShapes-isPointInPath-001
Blocks: 554013
Status: REOPENED → NEW
Keywords: dev-doc-needed
(Assignee)

Comment 15

6 years ago
Created attachment 533682 [details] [diff] [review]
updated patch

This is an updated patch.
Attachment #290828 - Attachment is obsolete: true
Attachment #533682 - Flags: review?(joe)
Comment on attachment 533682 [details] [diff] [review]
updated patch

Review of attachment 533682 [details] [diff] [review]:
-----------------------------------------------------------------

What should we do about the spec issue? The spec needs to be changed if everyone else does something different.
Attachment #533682 - Flags: superreview?(roc)
Attachment #533682 - Flags: review?(joe)
Attachment #533682 - Flags: review+
(Assignee)

Comment 17

6 years ago
Everyone else is doing something different, but they're all doing the same thing: following the spec.
Comment on attachment 533682 [details] [diff] [review]
updated patch

Review of attachment 533682 [details] [diff] [review]:
-----------------------------------------------------------------

Benjamin's right. This change makes us follow the spec.
Attachment #533682 - Flags: superreview?(roc) → superreview+
Keywords: checkin-needed
http://hg.mozilla.org/mozilla-central/rev/8a133638f5b6
Assignee: nobody → benjamin
Status: NEW → RESOLVED
Last Resolved: 10 years ago6 years ago
Keywords: checkin-needed
Resolution: --- → FIXED
Target Milestone: --- → mozilla7
Documentation updated:

https://developer.mozilla.org/en/DOM/CanvasRenderingContext2D#isPointInPath()

And mentioned on Firefox 7 for developers.
Keywords: dev-doc-needed → dev-doc-complete
Build identifier: Mozilla/5.0 (X11; Linux x86_64; rv:7.0) Gecko/20100101 Firefox/7.0

All tests mentioned in comment 7 , comment 10 and comment 14 passed. Marking bug as VERIFIED-FIXED.
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.