Re: The canvas element (detailed review)

----- Original Message ----- 
From: "Philip Taylor" <philip@zaynar.demon.co.uk>
To: "Andrew Fedoniouk" <news@terrainformatica.com>
Cc: <public-html@w3.org>
Sent: Saturday, August 04, 2007 5:35 AM
Subject: 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.

Beg my pardon but I cannot find where exactly it "suggests null should be
accepted as an object-implementing-an-interface".

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

If destination rectangle is not empty and one
of dimensions of source rectangle is less than device unit of the image
(in case of bitmaps it is a bitmap pixel) then exception should be thrown
(or any other failure indicator). This is very close to divide-by-zero case.

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

Fair enough.

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

I believe that defining something like:

ctx.interpolationMode = ...;

is the best what we can do. Having it you can define what would be
a default value of the attribute. Options other than
that are rather esoteric than practical.

>> Andrew Fedoniouk.
>> http://terrainformatica.com
>
> -- 
> Philip Taylor
> philip@zaynar.demon.co.uk
> 

Received on Saturday, 4 August 2007 17:59:35 UTC