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  wrote:

>
>
>
> On Mon, Mar 17, 2014 at 2:30 PM, Justin Novosad  wrote:
>
>>
>>
>>
>> On Mon, Mar 17, 2014 at 2:18 PM, Rik Cabanier  wrote:
>>
>>>
>>>
>>>
>>> On Mon, Mar 17, 2014 at 1:47 PM, Justin Novosad 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.
>

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 Rik Cabanier
On Mon, Mar 17, 2014 at 2:30 PM, Justin Novosad  wrote:

>
>
>
> On Mon, Mar 17, 2014 at 2:18 PM, Rik Cabanier  wrote:
>
>>
>>
>>
>> On Mon, Mar 17, 2014 at 1:47 PM, Justin Novosad  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-17 Thread Justin Novosad
On Mon, Mar 17, 2014 at 2:18 PM, Rik Cabanier  wrote:

>
>
>
> On Mon, Mar 17, 2014 at 1:47 PM, Justin Novosad  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 1:47 PM, Justin Novosad  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
>
>
>
>> 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?
>

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. See why I kept the fix on the
backburner? :-)


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  wrote:

>
>
>
> On Mon, Mar 17, 2014 at 2:06 PM, Rik Cabanier  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 Dirk Schulze

On Mar 17, 2014, at 9:23 PM, Justin Novosad  wrote:

> 
> 
> 
> On Mon, Mar 17, 2014 at 2:06 PM, Rik Cabanier  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 Justin Novosad
On Mon, Mar 17, 2014 at 2:06 PM, Rik Cabanier  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 Rik Cabanier
On Mon, Mar 17, 2014 at 10:18 AM, Justin Novosad  wrote:

>
>
>
> On Mon, Mar 17, 2014 at 12:59 PM, Rik Cabanier  wrote:
>
>>
>>
>>
>> On Mon, Mar 17, 2014 at 8:45 AM, Justin Novosad  wrote:
>>
>>> On Mon, Mar 17, 2014 at 11:35 AM, Dirk Schulze 
>>> 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 12:59 PM, Rik Cabanier  wrote:

>
>
>
> On Mon, Mar 17, 2014 at 8:45 AM, Justin Novosad  wrote:
>
>> On Mon, Mar 17, 2014 at 11:35 AM, Dirk Schulze 
>> 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 8:45 AM, Justin Novosad  wrote:

> On Mon, Mar 17, 2014 at 11:35 AM, Dirk Schulze  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 11:35 AM, Dirk Schulze  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?


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

2014-03-17 Thread Dirk Schulze

On Mar 17, 2014, at 3:49 PM, Justin Novosad  wrote:

> On Fri, Mar 14, 2014 at 4:50 PM, Ian Hickson  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 Justin Novosad
On Fri, Mar 14, 2014 at 4:50 PM, Ian Hickson  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-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  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 Rik Cabanier
On Thu, Feb 6, 2014 at 2:14 PM, Justin Novosad  wrote:

> On Tue, Jul 23, 2013 at 2:11 PM, Ian Hickson  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

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 Justin Novosad
On Tue, Jul 23, 2013 at 2:11 PM, Ian Hickson  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

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-22 Thread Dirk Schulze

On Jul 18, 2013, at 7:49 PM, Ian Hickson  wrote:

> 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.

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.

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

In both cases the transformation matrix is not invertible. I do not disagree.

> 
> 
>> 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, it is not clear which behavior is 
correct. Especially regarding that you can building a path over different 
context states and transforms per context states the this should be specified.

Dirk

> 
> 
>> 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.   `._.-(,_..'--(,_..'`-.;.'



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:


  
  
  
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();
}
  
  

  






Example 2:


  
  
  
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();
}