Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-20 Thread Rik Cabanier
On Mon, Mar 17, 2014 at 2:41 PM, Rik Cabanier caban...@gmail.com wrote:




 On Mon, Mar 17, 2014 at 2:30 PM, Justin Novosad ju...@google.com wrote:




 On Mon, Mar 17, 2014 at 2:18 PM, Rik Cabanier caban...@gmail.com wrote:




 On Mon, Mar 17, 2014 at 1:47 PM, Justin Novosad ju...@google.comwrote:





 I have a fix in flight that fixes that problem in Blink by storing
 the current path in transformed coordinates instead. I've had the fix on
 the back burner pending the outcome of this thread.


 That seems like an expensive solution because this causes the
 coordinates to be transformed twice.
 Why not store the matrix that was applied to the path coordinates and
 use that to undo the transformation?


 Dirk and I looked over the WebKit code and it's actually already doing
 this.


 Good, maybe that can be the reference then.




 If we decide that the right thing is to do nothing when when the CTM is
 non-invertible, then sure, we can just do that. The idea of storing the
 current path in transformed coordinates was to also support drawing with a
 non-invertible CTM, like Firefox does, which is what Ian stated was the
 correct behavior earlier in this thread.


 yeah, but then FF bails at draw time anyway.


 Only if the CTM is still non-invertible at draw time.  If the CTM was
 transiently non-invertible during the path construction, FF produces
 results consistent with applying the transform to the points used to
 construct the path, which is technically compliant with the current wording
 of the spec.


 That's correct. If someone did this in Firefox:

 ctx.setTransform(1,1,1,1,0,0);

 ctx.moveto(0,0);

 ctx.lineTo(10,0);

 ctx,setTransform(1,0,0,1,0,0);

 ctx.fill();

 the end result would be a line from (0,0) to (10, 10). (IE does this as
 well).
 Nothing draws in Safari and Chrome currently.


It would be great if we could get clarification on this.
Firefox and IE are conformant per the spec when it comes to drawing paths
but not fill/stroke/clip. Supporting this small edge case comes at a large
cost in Firefox and likely also IE.

Many APIs in canvas are running into this issue which results in lack of
interoperability.


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-17 Thread Justin Novosad
On Fri, Mar 14, 2014 at 4:50 PM, Ian Hickson i...@hixie.ch wrote:

 On Fri, 7 Feb 2014, Justin Novosad wrote:
   
Current text: If the point (x0, y0) is equal to the point (x1, y1),
or if the point (x1, y1) is equal to the point (x2, y2), or if both
radiusX and radiusY are zero, then the method must add the point
(x1, y1) to the subpath, and connect that point to the previous
point (x0, y0) by a straight line.
 
  With arcTo, the first point (x0, y0) may have been added to the current
  subpath using a different CTM. So to bring it into the local space of
  the current primitive, we need an invertible CTM.

 What I don't understand is why you can't draw the curve in the transformed
 space instead of the 1:1 coordinate space. You have to transform it
 eventually, right? And the points will end up simply transformed. So you
 can easily compare the points in the transformed space. All the transforms
 are affine, so what's a straight line isn't impacted. Can't you just draw
 the transformed arc instead of first drawing the circular arc and then
 transforming it?


 Maybe what I'm saying is obviously dumb for some reason, but I'm not
 understanding why, if so... (not that I'm a graphics guy, obviously.


Hmmm, I gave this a bit more thought...  To apply the construction
algorithm in transformed space, the ellipse parameters (radiusX, radiusY,
rotation) would have to be transformed. Transforming the parameters would
be intractable under a projective transform (e.g. perspective), but since
we are limitted to affine transforms, it can be done.  Now, in the case of
a non-invertible CTM, we would end up with radiusX or radiusY or both equal
to zero.  And what happens when you have that?  Your arcTo just turned into
lineTo(x1, y1). Tada!









 --
 Ian Hickson   U+1047E)\._.,--,'``.fL
 http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-17 Thread Dirk Schulze

On Mar 17, 2014, at 3:49 PM, Justin Novosad ju...@google.com wrote:

 On Fri, Mar 14, 2014 at 4:50 PM, Ian Hickson i...@hixie.ch wrote:
 
 On Fri, 7 Feb 2014, Justin Novosad wrote:
 
 Current text: If the point (x0, y0) is equal to the point (x1, y1),
 or if the point (x1, y1) is equal to the point (x2, y2), or if both
 radiusX and radiusY are zero, then the method must add the point
 (x1, y1) to the subpath, and connect that point to the previous
 point (x0, y0) by a straight line.
 
 With arcTo, the first point (x0, y0) may have been added to the current
 subpath using a different CTM. So to bring it into the local space of
 the current primitive, we need an invertible CTM.
 
 What I don't understand is why you can't draw the curve in the transformed
 space instead of the 1:1 coordinate space. You have to transform it
 eventually, right? And the points will end up simply transformed. So you
 can easily compare the points in the transformed space. All the transforms
 are affine, so what's a straight line isn't impacted. Can't you just draw
 the transformed arc instead of first drawing the circular arc and then
 transforming it?
 
 
 Maybe what I'm saying is obviously dumb for some reason, but I'm not
 understanding why, if so... (not that I'm a graphics guy, obviously.
 
 
 Hmmm, I gave this a bit more thought...  To apply the construction
 algorithm in transformed space, the ellipse parameters (radiusX, radiusY,
 rotation) would have to be transformed. Transforming the parameters would
 be intractable under a projective transform (e.g. perspective), but since
 we are limitted to affine transforms, it can be done.  Now, in the case of
 a non-invertible CTM, we would end up with radiusX or radiusY or both equal
 to zero.  And what happens when you have that?  Your arcTo just turned into
 lineTo(x1, y1). Tada!

Why does radiusX or radiusY need to be zero? Because you define it that way for 
a non-invertible matrix? That makes sense for scale(0,0). What about infinity 
or NaN? If Ian didn’t update the spec then this is still undefined and 
therefore up to the UA to decide.

Greetings,
Dirk

 
 
 
 
 
 
 
 
 
 --
 Ian Hickson   U+1047E)\._.,--,'``.fL
 http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
 



Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-17 Thread Rik Cabanier
On Mon, Mar 17, 2014 at 8:45 AM, Justin Novosad ju...@google.com wrote:

 On Mon, Mar 17, 2014 at 11:35 AM, Dirk Schulze dschu...@adobe.com wrote:

 
   Hmmm, I gave this a bit more thought...  To apply the construction
   algorithm in transformed space, the ellipse parameters (radiusX,
 radiusY,
   rotation) would have to be transformed. Transforming the parameters
 would
   be intractable under a projective transform (e.g. perspective), but
 since
   we are limitted to affine transforms, it can be done.  Now, in the case
  of
   a non-invertible CTM, we would end up with radiusX or radiusY or both
  equal
   to zero.  And what happens when you have that?  Your arcTo just turned
  into
   lineTo(x1, y1). Tada!
 
  Why does radiusX or radiusY need to be zero? Because you define it that
  way for a non-invertible matrix? That makes sense for scale(0,0). What
  about infinity or NaN? If Ian didn't update the spec then this is still
  undefined and therefore up to the UA to decide.
 
 
 Oh yeah, I was totally forgetting about singularities caused by non-finite
 values.  Could we just the same agree to resolve that case by treating
 arcTo as lineTo(x1, y1) in the case of a non-invertible CTM?  Or do you
 think there is a more logical thing to do?


Make a clean cut and define that drawing operators are ignored when there's
a non-invertible matrix.


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-17 Thread Justin Novosad
On Mon, Mar 17, 2014 at 12:59 PM, Rik Cabanier caban...@gmail.com wrote:




 On Mon, Mar 17, 2014 at 8:45 AM, Justin Novosad ju...@google.com wrote:

 On Mon, Mar 17, 2014 at 11:35 AM, Dirk Schulze dschu...@adobe.com
 wrote:

 
   Hmmm, I gave this a bit more thought...  To apply the construction
   algorithm in transformed space, the ellipse parameters (radiusX,
 radiusY,
   rotation) would have to be transformed. Transforming the parameters
 would
   be intractable under a projective transform (e.g. perspective), but
 since
   we are limitted to affine transforms, it can be done.  Now, in the
 case
  of
   a non-invertible CTM, we would end up with radiusX or radiusY or both
  equal
   to zero.  And what happens when you have that?  Your arcTo just turned
  into
   lineTo(x1, y1). Tada!
 
  Why does radiusX or radiusY need to be zero? Because you define it that
  way for a non-invertible matrix? That makes sense for scale(0,0). What
  about infinity or NaN? If Ian didn’t update the spec then this is still
  undefined and therefore up to the UA to decide.
 
 
 Oh yeah, I was totally forgetting about singularities caused by non-finite
 values.  Could we just the same agree to resolve that case by treating
 arcTo as lineTo(x1, y1) in the case of a non-invertible CTM?  Or do you
 think there is a more logical thing to do?


 Make a clean cut and define that drawing operators are ignored when
 there's a non-invertible matrix.

 I could totally go for that, but you are talking about going back on the
spec of a feature that has shipped, as opposed to clarifying edges cases.
Maybe that would be fine in this case though...


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-17 Thread Rik Cabanier
On Mon, Mar 17, 2014 at 10:18 AM, Justin Novosad ju...@google.com wrote:




 On Mon, Mar 17, 2014 at 12:59 PM, Rik Cabanier caban...@gmail.com wrote:




 On Mon, Mar 17, 2014 at 8:45 AM, Justin Novosad ju...@google.com wrote:

 On Mon, Mar 17, 2014 at 11:35 AM, Dirk Schulze dschu...@adobe.com
 wrote:

 
   Hmmm, I gave this a bit more thought...  To apply the construction
   algorithm in transformed space, the ellipse parameters (radiusX,
 radiusY,
   rotation) would have to be transformed. Transforming the parameters
 would
   be intractable under a projective transform (e.g. perspective), but
 since
   we are limitted to affine transforms, it can be done.  Now, in the
 case
  of
   a non-invertible CTM, we would end up with radiusX or radiusY or both
  equal
   to zero.  And what happens when you have that?  Your arcTo just
 turned
  into
   lineTo(x1, y1). Tada!
 
  Why does radiusX or radiusY need to be zero? Because you define it that
  way for a non-invertible matrix? That makes sense for scale(0,0). What
  about infinity or NaN? If Ian didn't update the spec then this is still
  undefined and therefore up to the UA to decide.
 
 
 Oh yeah, I was totally forgetting about singularities caused by
 non-finite
 values.  Could we just the same agree to resolve that case by treating
 arcTo as lineTo(x1, y1) in the case of a non-invertible CTM?  Or do you
 think there is a more logical thing to do?


 Make a clean cut and define that drawing operators are ignored when
 there's a non-invertible matrix.

 I could totally go for that, but you are talking about going back on the
 spec of a feature that has shipped, as opposed to clarifying edges cases.
 Maybe that would be fine in this case though...


I'm unsure if anyone has shipped that part of the spec. There's certainly
no interop...

Looking at the implementation in Blink and WebKit, all of the drawing
methods and fill/stroke/clip start with:

if (!isTransformInvertible())
return;


At first glance, Firefox seems to do what the spec says (which results in
slow double transforming of all coordinates) but then they punt as well:

Matrix inverse = mTarget-GetTransform();
if (!inverse.Invert()) {

NS_WARNING(Could not invert transform);

return;

}


So, what we could say is:
- when drawing paths, ignore all calls if the matrix is non-invertible
(WebKit and Blink do this)
- when filling/stroking/clipping, ignore all calls if the matrix is
non-invertible (Firefox, WebKit and Blink do this)


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-17 Thread Justin Novosad
On Mon, Mar 17, 2014 at 2:06 PM, Rik Cabanier caban...@gmail.com wrote:





 Make a clean cut and define that drawing operators are ignored when
 there's a non-invertible matrix.

 I could totally go for that, but you are talking about going back on the
 spec of a feature that has shipped, as opposed to clarifying edges cases.
 Maybe that would be fine in this case though...


 I'm unsure if anyone has shipped that part of the spec. There's certainly
 no interop...


Plenty of browser have shipped drawing paths to canvas. I agree about the
no interop part. It is the main reason I think it may still be acceptable
to redefine the spec.



 Looking at the implementation in Blink and WebKit, all of the drawing
 methods and fill/stroke/clip start with:

 if (!isTransformInvertible())
 return;


 At first glance, Firefox seems to do what the spec says (which results in
 slow double transforming of all coordinates) but then they punt as well:

 Matrix inverse = mTarget-GetTransform();
 if (!inverse.Invert()) {

 NS_WARNING(Could not invert transform);

 return;

 }


 So, what we could say is:
 - when drawing paths, ignore all calls if the matrix is non-invertible
 (WebKit and Blink do this)
 - when filling/stroking/clipping, ignore all calls if the matrix is
 non-invertible (Firefox, WebKit and Blink do this)


Yes, but there is still an issue that causes problems in Blink/WebKit:
because the canvas rendering context stores its path in local
(untransformed) space, whenever the CTM changes, the path needs to be
transformed to follow the new local spcae.  This transform requires the CTM
to be invertible. So now webkit and blink have a bug that causes all
previously recorded parts of the current path to be discarded when the CTM
becomes non-invertible (even if it is only temporarily non-invertible, even
if the current path is not even touched while the matrix is
non-invertible). I have a fix in flight that fixes that problem in Blink by
storing the current path in transformed coordinates instead. I've had the
fix on the back burner pending the outcome of this thread.


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-17 Thread Dirk Schulze

On Mar 17, 2014, at 9:23 PM, Justin Novosad ju...@google.com wrote:

 
 
 
 On Mon, Mar 17, 2014 at 2:06 PM, Rik Cabanier caban...@gmail.com wrote:
 
 
 
 
 Make a clean cut and define that drawing operators are ignored when there's a 
 non-invertible matrix. 
 
 I could totally go for that, but you are talking about going back on the spec 
 of a feature that has shipped, as opposed to clarifying edges cases. Maybe 
 that would be fine in this case though...
 
 I'm unsure if anyone has shipped that part of the spec. There's certainly no 
 interop...
 
 Plenty of browser have shipped drawing paths to canvas. I agree about the no 
 interop part. It is the main reason I think it may still be acceptable to 
 redefine the spec.
  
 
 Looking at the implementation in Blink and WebKit, all of the drawing methods 
 and fill/stroke/clip start with:
 if (!isTransformInvertible())
 return; 
 
 At first glance, Firefox seems to do what the spec says (which results in 
 slow double transforming of all coordinates) but then they punt as well:
 Matrix inverse = mTarget-GetTransform();
 if (!inverse.Invert()) {
 NS_WARNING(Could not invert transform);
 return;
 }
 
 So, what we could say is:
 - when drawing paths, ignore all calls if the matrix is non-invertible 
 (WebKit and Blink do this)
 - when filling/stroking/clipping, ignore all calls if the matrix is 
 non-invertible (Firefox, WebKit and Blink do this)
 
 Yes, but there is still an issue that causes problems in Blink/WebKit: 
 because the canvas rendering context stores its path in local (untransformed) 
 space, whenever the CTM changes, the path needs to be transformed to follow 
 the new local spcae.  This transform requires the CTM to be invertible. So 
 now webkit and blink have a bug that causes all previously recorded parts of 
 the current path to be discarded when the CTM becomes non-invertible (even if 
 it is only temporarily non-invertible, even if the current path is not even 
 touched while the matrix is non-invertible). I have a fix in flight that 
 fixes that problem in Blink by storing the current path in transformed 
 coordinates instead. I've had the fix on the back burner pending the outcome 
 of this thread.

Are you sure about this? The path should stay untouched during the time the CTM 
is not invertible. At least in WebKit I can not remember that I see the path 
discarded. As Rik quoted in the code snippet, we just return silently and do 
not touch the path and avoid daring operations.

Greetings,
Dirk

 



Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-17 Thread Rik Cabanier
On Mon, Mar 17, 2014 at 1:23 PM, Justin Novosad ju...@google.com wrote:




 On Mon, Mar 17, 2014 at 2:06 PM, Rik Cabanier caban...@gmail.com wrote:





 Make a clean cut and define that drawing operators are ignored when
 there's a non-invertible matrix.

 I could totally go for that, but you are talking about going back on
 the spec of a feature that has shipped, as opposed to clarifying edges
 cases. Maybe that would be fine in this case though...


 I'm unsure if anyone has shipped that part of the spec. There's certainly
 no interop...


 Plenty of browser have shipped drawing paths to canvas. I agree about the
 no interop part. It is the main reason I think it may still be acceptable
 to redefine the spec.


Sure, but no one implemented transforming of the path as the spec
describes. At the time the drawing operation happens, all browsers have the
path in the local CTM.


 Looking at the implementation in Blink and WebKit, all of the drawing
 methods and fill/stroke/clip start with:

 if (!isTransformInvertible())
 return;


 At first glance, Firefox seems to do what the spec says (which results in
 slow double transforming of all coordinates) but then they punt as well:

 Matrix inverse = mTarget-GetTransform();
 if (!inverse.Invert()) {

 NS_WARNING(Could not invert transform);

 return;

 }


 So, what we could say is:
 - when drawing paths, ignore all calls if the matrix is non-invertible
 (WebKit and Blink do this)
 - when filling/stroking/clipping, ignore all calls if the matrix is
 non-invertible (Firefox, WebKit and Blink do this)


 Yes, but there is still an issue that causes problems in Blink/WebKit:
 because the canvas rendering context stores its path in local
 (untransformed) space, whenever the CTM changes, the path needs to be
 transformed to follow the new local spcae.  This transform requires the CTM
 to be invertible. So now webkit and blink have a bug that causes all
 previously recorded parts of the current path to be discarded when the CTM
 becomes non-invertible (even if it is only temporarily non-invertible, even
 if the current path is not even touched while the matrix is
 non-invertible).


This was something that was introduced by the Blink team after they
branched.
WebKit doesn't do this flagging so if a non-invertible matrix is reset, the
old path will still be around.


 I have a fix in flight that fixes that problem in Blink by storing the
 current path in transformed coordinates instead. I've had the fix on the
 back burner pending the outcome of this thread.


That seems like an expensive solution because this causes the coordinates
to be transformed twice.
Why not store the matrix that was applied to the path coordinates and use
that to undo the transformation?


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-17 Thread Rik Cabanier
On Mon, Mar 17, 2014 at 1:47 PM, Justin Novosad ju...@google.com wrote:





 I have a fix in flight that fixes that problem in Blink by storing the
 current path in transformed coordinates instead. I've had the fix on the
 back burner pending the outcome of this thread.


 That seems like an expensive solution because this causes the coordinates
 to be transformed twice.
 Why not store the matrix that was applied to the path coordinates and use
 that to undo the transformation?


Dirk and I looked over the WebKit code and it's actually already doing this.


 If we decide that the right thing is to do nothing when when the CTM is
 non-invertible, then sure, we can just do that. The idea of storing the
 current path in transformed coordinates was to also support drawing with a
 non-invertible CTM, like Firefox does, which is what Ian stated was the
 correct behavior earlier in this thread.


yeah, but then FF bails at draw time anyway.
IMO no author relies on behavior when there's a non-invertible matrix so we
should just implement the simplest and most efficient solution.


 See why I kept the fix on the backburner? :-)


:-P yes


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-17 Thread Justin Novosad
On Mon, Mar 17, 2014 at 2:18 PM, Rik Cabanier caban...@gmail.com wrote:




 On Mon, Mar 17, 2014 at 1:47 PM, Justin Novosad ju...@google.com wrote:





 I have a fix in flight that fixes that problem in Blink by storing the
 current path in transformed coordinates instead. I've had the fix on the
 back burner pending the outcome of this thread.


 That seems like an expensive solution because this causes the
 coordinates to be transformed twice.
 Why not store the matrix that was applied to the path coordinates and
 use that to undo the transformation?


 Dirk and I looked over the WebKit code and it's actually already doing
 this.


Good, maybe that can be the reference then.




 If we decide that the right thing is to do nothing when when the CTM is
 non-invertible, then sure, we can just do that. The idea of storing the
 current path in transformed coordinates was to also support drawing with a
 non-invertible CTM, like Firefox does, which is what Ian stated was the
 correct behavior earlier in this thread.


 yeah, but then FF bails at draw time anyway.


Only if the CTM is still non-invertible at draw time.  If the CTM was
transiently non-invertible during the path construction, FF produces
results consistent with applying the transform to the points used to
construct the path, which is technically compliant with the current wording
of the spec.


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-17 Thread Rik Cabanier
On Mon, Mar 17, 2014 at 2:30 PM, Justin Novosad ju...@google.com wrote:




 On Mon, Mar 17, 2014 at 2:18 PM, Rik Cabanier caban...@gmail.com wrote:




 On Mon, Mar 17, 2014 at 1:47 PM, Justin Novosad ju...@google.com wrote:





 I have a fix in flight that fixes that problem in Blink by storing the
 current path in transformed coordinates instead. I've had the fix on the
 back burner pending the outcome of this thread.


 That seems like an expensive solution because this causes the
 coordinates to be transformed twice.
 Why not store the matrix that was applied to the path coordinates and
 use that to undo the transformation?


 Dirk and I looked over the WebKit code and it's actually already doing
 this.


 Good, maybe that can be the reference then.




 If we decide that the right thing is to do nothing when when the CTM is
 non-invertible, then sure, we can just do that. The idea of storing the
 current path in transformed coordinates was to also support drawing with a
 non-invertible CTM, like Firefox does, which is what Ian stated was the
 correct behavior earlier in this thread.


 yeah, but then FF bails at draw time anyway.


 Only if the CTM is still non-invertible at draw time.  If the CTM was
 transiently non-invertible during the path construction, FF produces
 results consistent with applying the transform to the points used to
 construct the path, which is technically compliant with the current wording
 of the spec.


That's correct. If someone did this in Firefox:

ctx.setTransform(1,1,1,1,0,0);

ctx.moveto(0,0);

ctx.lineTo(10,0);

ctx,setTransform(1,0,0,1,0,0);

ctx.fill();

the end result would be a line from (0,0) to (10, 10). (IE does this as
well).
Nothing draws in Safari and Chrome currently.


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-03-14 Thread Ian Hickson
On Fri, 7 Feb 2014, Justin Novosad wrote:
  
   Current text: If the point (x0, y0) is equal to the point (x1, y1), 
   or if the point (x1, y1) is equal to the point (x2, y2), or if both 
   radiusX and radiusY are zero, then the method must add the point 
   (x1, y1) to the subpath, and connect that point to the previous 
   point (x0, y0) by a straight line.
 
 With arcTo, the first point (x0, y0) may have been added to the current 
 subpath using a different CTM. So to bring it into the local space of 
 the current primitive, we need an invertible CTM.

What I don't understand is why you can't draw the curve in the transformed 
space instead of the 1:1 coordinate space. You have to transform it 
eventually, right? And the points will end up simply transformed. So you 
can easily compare the points in the transformed space. All the transforms 
are affine, so what's a straight line isn't impacted. Can't you just draw 
the transformed arc instead of first drawing the circular arc and then 
transforming it?

Maybe what I'm saying is obviously dumb for some reason, but I'm not 
understanding why, if so... (not that I'm a graphics guy, obviously).

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-02-07 Thread Justin Novosad
On Thu, Feb 6, 2014 at 2:55 PM, Ian Hickson i...@hixie.ch wrote:

 On Thu, 6 Feb 2014, Justin Novosad wrote:
 
  I am looking into correcting Chrome's behavior to make it spec-compliant
 in
  this case.  There is one specific primitive that is proving problematic:
  arcTo
 
  The problem is that the algorithm needs to bring the last point in the
  subpath into the arc's local coordinate space, which requires inverting
  the CTM.
 
  Current text: If the point (x0, y0) is equal to the point (x1, y1), or
  if the point (x1, y1) is equal to the point (x2, y2), or if both radiusX
  and radiusY are zero, then the method must add the point (x1, y1) to the
  subpath, and connect that point to the previous point (x0, y0) by a
  straight line.

 I don't understand why this needs the last point in the subpath to be
 converted to the arc's local coordinate space, rather than the other way
 around. Can you elaborate? why can't you convert all the points to the
 current coordinate space before doing the comparisons?


The arc is expected to be circular (as opposed to elliptical) in local
space.  If we apply the construction algorithm post-transform, you may not
get the same result. For example, a non-uniform scale will mess things up.


 (I'm probably missing something critical here.)


  As far as I can tell, quadraticCurveTo and bezierCurveTo do not have
  this problem because the curves can be computed by first transforming
  all points to global coordinate space, to compute the curves in global
  space.

 Why is this not the case for arcs?


With arcs (as opposed to arcTo), the last point in the subpath does not
enter into the curve construction algorithm (we just draw a straight line
from the last point in the subpath to the starting point of the arc).
 Therefore, all the points use for constructing the curve are in the same
coordinate space.  With arcTo, the first point (x0, y0) may have been added
to the current subpath using a different CTM. So to bring it into the local
space of the current primitive, we need an invertible CTM.


 --
 Ian Hickson   U+1047E)\._.,--,'``.fL
 http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-02-06 Thread Justin Novosad
On Tue, Jul 23, 2013 at 2:11 PM, Ian Hickson i...@hixie.ch wrote:


   The second does setTransform(0,0,0,0,0,0), which should reset the CTM
   to a zero matrix (again, not invertible). IE, Opera and FF draw a
   line to 0,0 and close the path afterwards (which kind of makes sense,
   since the universe is convoluted to one point). WebKit refuses the
   lineTo command and closes the path as expected.
  
   WebKit seems to just be wrong here, and the others right.
 
  Since this is not written in the spec

 As far as I can tell, it _is_ written in the spec. scale(0,0) would reduce
 all coordinates and lines and so forth to 0,0. That's what the spec
 requires. I don't see the problem here.


I am looking into correcting Chrome's behavior to make it spec-compliant in
this case.  There is one specific primitive that is proving problematic:
arcTo
The problem is that the algorithm needs to bring the last point in the
subpath into the arc's local coordinate space, which requires inverting the
CTM.

I would like to suggest a small amendment to the spec:

Current text:
If the point (x0, y0) is equal to the point (x1, y1), or if the point (x1,
y1) is equal to the point (x2, y2), or if both radiusX and radiusY are
zero, then the method must add the point (x1, y1) to the subpath, and
connect that point to the previous point (x0, y0) by a straight line.

Suggested addition:
If the current transformation matrix is not invertible, then the method
must add the point (x1, y1) to the subpath, and connect that point to the
previous point in the subpath by a straight line.

Note: I used previous point in the subpath rather than (x0, y0),
because the point is only defined in global space, and not in local space
due to the CTM being singular.

I have not yet investigated what other browsers are doing in this case.
Feedback from other implementers would be appreciated.

As far as I can tell, quadraticCurveTo and bezierCurveTo do not have this
problem because the curves can be computed by first transforming all points
to global coordinate space, to compute the curves in global space.

Thanks,

 Justin


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-02-06 Thread Ian Hickson
On Thu, 6 Feb 2014, Justin Novosad wrote:

 I am looking into correcting Chrome's behavior to make it spec-compliant in
 this case.  There is one specific primitive that is proving problematic:
 arcTo

 The problem is that the algorithm needs to bring the last point in the 
 subpath into the arc's local coordinate space, which requires inverting 
 the CTM.
 
 Current text: If the point (x0, y0) is equal to the point (x1, y1), or 
 if the point (x1, y1) is equal to the point (x2, y2), or if both radiusX 
 and radiusY are zero, then the method must add the point (x1, y1) to the 
 subpath, and connect that point to the previous point (x0, y0) by a 
 straight line.

I don't understand why this needs the last point in the subpath to be 
converted to the arc's local coordinate space, rather than the other way 
around. Can you elaborate? why can't you convert all the points to the 
current coordinate space before doing the comparisons?

(I'm probably missing something critical here.)


 As far as I can tell, quadraticCurveTo and bezierCurveTo do not have 
 this problem because the curves can be computed by first transforming 
 all points to global coordinate space, to compute the curves in global 
 space.

Why is this not the case for arcs?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2014-02-06 Thread Rik Cabanier
On Thu, Feb 6, 2014 at 2:14 PM, Justin Novosad ju...@google.com wrote:

 On Tue, Jul 23, 2013 at 2:11 PM, Ian Hickson i...@hixie.ch wrote:

 
The second does setTransform(0,0,0,0,0,0), which should reset the
 CTM
to a zero matrix (again, not invertible). IE, Opera and FF draw a
line to 0,0 and close the path afterwards (which kind of makes
 sense,
since the universe is convoluted to one point). WebKit refuses the
lineTo command and closes the path as expected.
   
WebKit seems to just be wrong here, and the others right.
  
   Since this is not written in the spec
 
  As far as I can tell, it _is_ written in the spec. scale(0,0) would
 reduce
  all coordinates and lines and so forth to 0,0. That's what the spec
  requires. I don't see the problem here.
 
 
 I am looking into correcting Chrome's behavior to make it spec-compliant in
 this case.


Wow. That would be really impressive!
Given the algorithm for 'tracing a path' [1], what would the following
fiddle look like? http://jsfiddle.net/bn3LF/4/



 There is one specific primitive that is proving problematic:
 arcTo
 The problem is that the algorithm needs to bring the last point in the
 subpath into the arc's local coordinate space, which requires inverting the
 CTM.

 I would like to suggest a small amendment to the spec:

 Current text:
 If the point (x0, y0) is equal to the point (x1, y1), or if the point (x1,
 y1) is equal to the point (x2, y2), or if both radiusX and radiusY are
 zero, then the method must add the point (x1, y1) to the subpath, and
 connect that point to the previous point (x0, y0) by a straight line.

 Suggested addition:
 If the current transformation matrix is not invertible, then the method
 must add the point (x1, y1) to the subpath, and connect that point to the
 previous point in the subpath by a straight line.

 Note: I used previous point in the subpath rather than (x0, y0),
 because the point is only defined in global space, and not in local space
 due to the CTM being singular.

 I have not yet investigated what other browsers are doing in this case.
 Feedback from other implementers would be appreciated.

 As far as I can tell, quadraticCurveTo and bezierCurveTo do not have this
 problem because the curves can be computed by first transforming all points
 to global coordinate space, to compute the curves in global space.


1:
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#trace-a-path


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2013-07-23 Thread Ian Hickson
On Mon, 22 Jul 2013, Dirk Schulze wrote:
  
  scale(0) is invalid, and should throw an exception.
 
 I don't think that we want to throw an exception on scale(0). No browser 
 does that today. WebKit did it in some places in the past but removed 
 the exceptions.

WebIDL says it should throw a TypeError, because it's missing an argument. 
(Step 4 of the overload resolution algorithm). Firefox, Chrome, and Safari 
all seem to do this.


  The second does setTransform(0,0,0,0,0,0), which should reset the CTM 
  to a zero matrix (again, not invertible). IE, Opera and FF draw a 
  line to 0,0 and close the path afterwards (which kind of makes sense, 
  since the universe is convoluted to one point). WebKit refuses the 
  lineTo command and closes the path as expected.
  
  WebKit seems to just be wrong here, and the others right.
 
 Since this is not written in the spec

As far as I can tell, it _is_ written in the spec. scale(0,0) would reduce 
all coordinates and lines and so forth to 0,0. That's what the spec 
requires. I don't see the problem here.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] [Canvas] Behavior on non-invertable CTM

2013-07-18 Thread Ian Hickson
On Tue, 29 Jan 2013, Dirk Schulze wrote:
 
 The spec doesn't have any wording about the behavior on non-invertible 
 CTMs on Canvas contexts. Is it still possible to add segments to the 
 current path once a CTM is not invertible anymore? Does the path get 
 rejected completely then? Implementations are fairly different.
 
 Here are two examples (code attached at the end of the mail as well):
 
 http://jsfiddle.net/Dghuh/1/
 http://jsfiddle.net/Dghuh/2/
 
 Note that the path is stroked after restoring the initial CTM in both 
 examples.
 
 The first one does scale(0), which should make the CTM non-invertibe, 
 WebKit still applies lineTo and closePath for some reason. IE and FF 
 refuse to draw anything.

scale(0) is invalid, and should throw an exception.

If you do scale(0,0), the browsers act the same as with your second test 
that uses setTransform() with 6 zeros.


 The second does setTransform(0,0,0,0,0,0), which should reset the CTM to 
 a zero matrix (again, not invertible). IE, Opera and FF draw a line to 
 0,0 and close the path afterwards (which kind of makes sense, since the 
 universe is convoluted to one point). WebKit refuses the lineTo command 
 and closes the path as expected.

WebKit seems to just be wrong here, and the others right.


 This is an edge case, but should still be clarified in the spec.

I don't understand what there is to clarify. In both cases, the behaviour 
seems well-defined: if you're transforming everything to zero, that's what 
the result will be. Zero. Firefox's behaviour is the right one.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


[whatwg] [Canvas] Behavior on non-invertable CTM

2013-01-29 Thread Dirk Schulze
Hi,

The spec doesn't have any wording about the behavior on non-invertible CTMs on 
Canvas contexts. Is it still possible to add segments to the current path once 
a CTM is not invertible anymore? Does the path get rejected completely then? 
Implementations are fairly different.

Here are two examples (code attached at the end of the mail as well):

http://jsfiddle.net/Dghuh/1/
http://jsfiddle.net/Dghuh/2/

Note that the path is stroked after restoring the initial CTM in both examples.

The first one does scale(0), which should make the CTM non-invertibe, WebKit 
still applies lineTo and closePath for some reason. IE and FF refuse to draw 
anything.

The second does setTransform(0,0,0,0,0), which should reset the CTM to a zero 
matrix (again, not invertible). IE, Opera and FF draw a line to 0,0 and close 
the path afterwards (which kind of makes sense, since the universe is 
convoluted to one point). WebKit refuses the lineTo command and closes the path 
as expected.

This is an edge case, but should still be clarified in the spec.

A possible (and maybe easiest) solution would be to refuse all values for 
transformation functions that cause an invertible matrix. On the other hand, 
all browsers allow setting  not invertible CTMs at the moment.

Greetings,
Dirk

Example 1:

head
  meta charset=utf-8
  title/title
  script
window.onload = function () {
var canvas = document.getElementById(canvas);
var ctx = canvas.getContext(2d);
ctx.moveTo(10,10);
ctx.lineTo(90,10);
ctx.lineTo(90,90);
ctx.lineTo(10,90);
ctx.save();
ctx.scale(0);
ctx.lineTo(45,45);
ctx.closePath();
ctx.restore();
ctx.strokeStyle= black;
ctx.stroke();
}
  /script
  style

  /style
/head
body
canvas id=canvas/canvas
/body


Example 2:

head
  meta charset=utf-8
  title/title
  script
window.onload = function () {
var canvas = document.getElementById(canvas);
var ctx = canvas.getContext(2d);
ctx.moveTo(10,10);
ctx.lineTo(90,10);
ctx.lineTo(90,90);
ctx.lineTo(10,90);
ctx.save();
ctx.setTransform(0,0,0,0,0,0);
ctx.lineTo(45,45);
ctx.closePath();
ctx.restore();
ctx.strokeStyle= black;
ctx.stroke();
}
  /script
  style

  /style
/head
body
canvas id=canvas/canvas
/body