Re: Some comments on The Canvas 2D API 1.0 Specification

Erik Dahlstrom wrote:
> On Thu, 01 Oct 2009 20:55:44 +0200, Frank Olivier <franko@microsoft.com> 
> wrote:
> 
>> Re Erik Dahlstrom's mail on Mon, 07 Sep 2009 14:54:29 +0200
>>
>>> 3.3 Compositing
>>>> lighter  A plus B. Display the sum of the source image and destination
>>>> image, with color values approaching 1 as a limit.
>>> Why isn't this named 'plus' or 'add' instead?

Because someone at Apple implementing the canvas API chose 'lighter' for 
CG's CompositePlusLighter mode (and 'darker' for CompositePlusDarker), 
and then it was never worth renaming.

>>> 'plus' would be consistent
>>> with PorterDuff, 'add' might be better if there's an intention to add a
>>> 'subtract' mode in the future.
>>
>> Safari 4 supports 'lighter' and 'darker' today.

Note that 'darker' was originally in the spec, but every implementation 
(Safari, Firefox, Opera) was different, and platform APIs don't seem to 
provide functionality that could be used to implement 'darker' 
interoperably, so the cost of supporting it properly was relatively 
high, and so it was removed from the spec. (It's a bug that some 
browsers continue to support it.)

>> Is your proposal to change 'lighten' to 'add'? I don't think this 
>> change is worth the compat impact, but I'd love to hear more opinions.
> 
> Well, if there really is that much content relying on that particular 
> functionality

http://google.com/codesearch?q=globalCompositeOperation.%2Alighter 
suggests that a number of people do use it. (Not a large number, but 
more than just test cases.)

> (from a draft spec no less)

That doesn't seem relevant when considering compatibility. The canvas 
spec has been quite stable and widely implemented and useful for a 
number of years, so people rely on it - e.g. a lot of people noticed and 
were unhappy when Firefox 2.0.0.10 broke drawImage 
(http://ejohn.org/blog/why-20011-happened-so-fast/). They don't care 
that the specification is only called a draft.

> an option would be to 
> keep the old keyword and add an alias that does the same thing.

That seems to me to have a reasonably significant cost (updating half a 
dozen canvas implementations, updating documentation and tutorials, 
confusing authors and breaking users during the years it takes to deploy 
updated browsers) with negligible benefit (the 'lighter' mode does 
indeed make things lighter, so it's not a bad name, and documentation 
can explain exactly what it does).

>>>> vendorName-operationName  Vendor-specific extensions to the list of
>>>> composition operators should use this syntax.
>>> Why is this needed? Isn't the getContext() method enough to deal with
>>> vendor-extensions?

Duplicating the entire 2D context API into a vendor-specific context 
doesn't seem like a good idea, because it would be confusing when 
someone tries to query state or draw things using both contexts at once. 
*Not* duplicating the context, and requiring authors to use both, would 
probably mean they have to do something like:

   getContext('2d').globalCompositeOperation = 'source-over';
   ...draw stuff with source-over...
   getContext('vnd-2dext').globalCompositeOperationOverride = 'dissolve';
   ...draw stuff with dissolve...
   getContext('vnd-2dext').globalCompositeOperationOverride = 'none';
   ...draw stuff with source-over...

where the state of both contexts interacts with drawing operations, and 
it's a lot more complex than simply having a new vendor-specific 
operation string.

If vendors are going to add non-standard composite operations, I expect 
they'd prefer to do it in the simplest way for authors, so it's useful 
for spec to tell them how to do it consistently and without conflicting 
with future standard composite operations.

I haven't seen any vendors wanting to add vendor-specific extensions 
here, so currently the text is unnecessary; I don't know if that will 
change in the future.

>> IMHO using a vendor-specific tag to an existing method using this 
>> mechanism is fine.
>>  [...]
>> IMHO getContent(vendor-extension) should be used when the vendor wants 
>> to add new *methods*.

Vendor-extension methods are sometimes added to the standard 2D context 
instead, e.g. mozDrawString, which seems fine (it avoids naming 
conflicts, and it's easier for authors than a new context).

New contexts are probably most useful when they're completely different 
to the 2d context, e.g. the moz-glweb20 3D context. In other cases, I 
think vendor-prefixed methods and properties and values are probably 
more approriate.

>> To check if a particular vendor-specific tag is supported, the 
>> following could be used:
>>
>> previous = context.globalCompositeOperation;
>> context.globalCompositeOperation = vendor-specific;
>> if (previous != context.globalCompositeOperation) do the 
>> vendor-specific drawing
>> (This relies on the "Unknown values are ignored" part of the spec)

For compatibility you'd need to add a try/catch since old Firefoxes 
(maybe new ones too?) throw instead of ignoring values, if I remember 
correctly.

-- 
Philip Taylor
pjt47@cam.ac.uk

Received on Monday, 26 October 2009 17:17:41 UTC