Re: The canvas element (detailed review)

Andrew Fedoniouk wrote:
> 
> ----- Original Message ----- From: "Philip Taylor" 
> <philip@zaynar.demon.co.uk>
> To: <public-html@w3.org>
> Sent: Friday, August 03, 2007 7:12 PM
> Subject: The canvas element (detailed review)
> 
> 
>> drawImage:
>>
>> "The image argument must be an instance of an HTMLImageElement or 
>> HTMLCanvasElement. If the image is of the wrong type, the 
>> implementation must raise a TYPE_MISMATCH_ERR exception." - what if it 
>> is the correct type but null? (The same applies to createPattern). 
>> (Currently, FF throws NS_ERROR_NOT_AVAILABLE, Opera throws 
>> TYPE_MISMATCH_ERR, Safari crashes.)

(Sorry, that's misleading - Safari with the latest WebKit throws a type 
error instead of crashing.)

> 'null' is a value of empty object reference. No object - no type. So "is 
> the correct type but null" is a bit confusing.

Languages other than JavaScript (e.g. Java) can have (statically-)typed 
null-valued variables, and 
<http://dev.w3.org/cvsweb/~checkout~/2006/webapi/Binding4DOM/Overview.html?rev=1.51&content-type=text/html;%20charset=utf-8#es-interface> 
suggests null should be accepted as an object-implementing-an-interface, 
so I think it's worth being explicit.

>> What should happen if sw = 0 or sh = 0? (Firefox draws nothing, Opera 
>> (9.2) draws something (top left pixel?), Safari 3 throws INDEX_SIZE_ERR.)

(Also misleading - FF3 draws the colour from point (sx, sy), which is 
just confusing if sx=sy=0 since the image is treated as transparent at 
its edges. FF2 and Opera also draw the colour from (sx, sy) but use the 
nearest edge pixels instead of transparent.)

> It should draw nothing - zero dimension is zero dimension.

But the destination rectangle has non-zero dimension, so it'd be 
reasonable to say that it should draw something into that destination 
rectangle; and it'd be reasonable to say that it's equivalent to 
drawImage(img, sx, sy, e, e, ...) as e tends towards zero, i.e. the 
(filtered) colour at point (sx, sy) on the image, which is what 
FF2/FF3/Opera do. (I think that's probably similarly reasonable to 
drawing nothing or throwing an exception.)

> Another interesting question is what should happen when sw, sh are 
> negative. Say if sh < 0 shall image be drawn as mirrored?

Ah, I didn't notice that case. FF/Opera/Safari all throw INDEX_SIZE_ERR, 
and the spec says to use INDEX_SIZE_ERR for negative dw or dh, and none 
of the rest of the API accepts negative-sized rectangles, so it seems 
sensible to throw.

>> It might be nice to say "Implementations should use bilinear filtering 
>> when resizing the image", so that implementations agree with each 
>> other except when they have reasons not to (e.g. resource constraints 
>> which make bilinear filtering too expensive). (At least, I think 
>> current implementations are doing bilinear filtering - is that correct?)
> 
> It should be either "unspecified" ...

Why leave it unspecified, rather than suggesting (not requiring) a 
sensible default that will encourage compatibility between implementations?

> ... or CanvasRenderingContext2D should have attribute of type
> enum ImageFilter
>    {
>        NoFilter,
>        Bilinear,
>        Hanning,
>        Hermite,
>        Quadratic,
>        Bicubic,
>        Catrom,
>        Spline16,
>        Spline36,
>        Blackman144,
>        ...
>    }
> 
> that would allow to select proper method.

Those options don't seem appropriate when doing graphics rather than 
image processing, judging by similar APIs: Quartz 2D gives options 
"none", "low", "high", "default"; Cairo gives "nearest", "bilinear", 
"fast", "good", "best"; Java 2D seemingly gives "quality", "speed", 
"default". If there was any choice, I believe it should be just between 
"fast" (typically nearest-neighbour) and "quality" (default; typically 
bilinear) since those are the most useful options and can be done quite 
easily in all implementations.

I would currently be in favour of allowing that kind of choice - my 
experience with Canvex was that drawImage took up a majority of the 
time, and it should get much better performance if it wasn't doing 
non-trivial filtering, and I'm in a better position than the browser to 
decide whether the quality tradeoff is acceptable. (I already 
implemented mipmapping to avoid quality issues when images are 
bilinearly rescaled below 50%, and so nearest-neighbour filtering 
wouldn't be significantly worse quality). The API seems easy to define, 
since "ctx.interpolationMode = 'speed' /* or 'quality' */;" is currently 
accepted (ignored) by browsers.

> Andrew Fedoniouk.
> http://terrainformatica.com

-- 
Philip Taylor
philip@zaynar.demon.co.uk

Received on Saturday, 4 August 2007 12:36:09 UTC