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

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

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

> 

Received on Monday, 17 March 2014 20:39:15 UTC