Re: [whatwg] [Canvas] Behavior on non-invertable CTM
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
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
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
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
> > > >> 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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(); }