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

Justin Novosad junov at google.com
Mon Mar 17 13:23:21 PDT 2014

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

More information about the whatwg mailing list