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

Rik Cabanier cabanier at gmail.com
Mon Mar 17 13:40:38 PDT 2014


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

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

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?



More information about the whatwg mailing list