[whatwg] Canvas spec issues

Philip Taylor excors+whatwg at gmail.com
Wed Apr 4 10:10:34 PDT 2007

Some more comments/suggestions/etc on the spec, from having tried to
test the stuff up to linear gradients [1].

All my comments on implementations are about Firefox trunk, Opera 9.10
(no different to 9.20), and Safari 2.0.4 (because that's the only one
for which I can find a free online screenshot generator...)


Relating to data: URLs:

"To prevent information leakage, the toDataURL() and getImageData()
methods should raise a security exception if the canvas ever had
images painted on it that originate from a domain other than the
domain of the script that painted the images onto the canvas." - is it
true/obvious that an image from a data: URL doesn't originate from any
domain at all and so it should be allowed?

Firefox and Opera [I haven't tested Safari] throw security exceptions
in that case, which is annoying - I believe it's not a security risk
since the only way you can draw a data: image is by having access to
the Image object and thus its src attribute, so you already have
access to the image data.

Relating to gradients:

"Otherwise, if it is ... a CanvasGradient or CanvasPattern, then an
object supporting those interfaces must be returned. Such objects are
opaque and therefore only useful for assigning to other attributes or
for comparison to other gradients or patterns." - what does "opaque"
mean? It doesn't seem to be defined here.

Should it be the case that "ctx.fillStyle === ctx.fillStyle" and
"ctx.fillStyle = grad; ctx.fillStyle === grad"? That seems necessary
if useful comparison is to be possible, but it doesn't seem to be what
the "must" statement says. And should it be that
"ctx.createLinearGradient(...) !== ctx.createLinearGradient(...)"?

Should it be that "ctx.fillStyle = grad; grad.addColorStop(...)" will
alter the currently-selected fill style, i.e. fillStyle has to store a
reference to the gradient instead of a copy? (If so, then
"ctx.fillStyle = grad; ctx.fillStyle.addColorStop(...)" should work
too, which is nice.)

(For those questions, the three tested implementations do seem to do
that [after accounting for Safari 2.0.4's lack of gradients in
fillRect] - see [2].)

"Immediately before the 0 offset and immediately after the 1 offset,
transparent black stops are be assumed." and "any points beyond the
start or end points are a transparent black."

That is not implemented interoperably [3], and it has been suggested
[4] that Firefox's behaviour might be better. FF extends the outermost
colour stops outwards forever - that is the most powerful approach,
since you can manually add transparent-black or black stops to
reproduce the behaviours of Opera (equivalent to the current spec) and

One issue with FF's behaviour is what to do when a linear gradient has
zero length (i.e. x0,y0 == x1,y1) - it could just be defined to be
equivalent to the first colour stop, which seems to be what FF does.

"The addColorStop(offset, color) method on the CanvasGradient
interface adds a new stop to a gradient. If the offset is less than 0
or greater than 1 then an INDEX_SIZE_ERR exception must be raised."

What if offset is NaN? That is neither less than 0 nor greater than 1.

What if multiple stops are added at the same offset? I would say
something along the lines of: "If there is already a stop at the same
/offset/, the new color stop must be treated as if its /offset/ is
greater than that of the earlier stop." i.e. the first stop added will
be closest to offset 0, and the last will be (infinitesimally) closest
to offset 1. Firefox and Opera appear to implement it that way; Safari
doesn't seem to have a consistent order at all. See [5].


Some points on pedantic standardese (given that [6] indicates it's
desirable to be precise about normative statements) (though I'm
uncertain on the correctness of some of these points, so please
disagree if I'm wrong):

"The width attribute defaults to 300, and the height attribute
defaults to 150." - should have "must"s.

"String comparisons should be literal and case-sensitive." - s/should/must/

"The save() method pushes ... The restore() method pops ... If there
is no saved state, the method does nothing." - should have "must"s.

globalCompositeOperation: "It must be set to a value from the
following list ... User agents must only recognise values that exactly
match the values given above." - but that conflicts with the
vendorName-operationName extensions, because authors and UAs have to
use values not in that list if they're going to use that extension
opportunity; and the vendorName-operationName syntax is only a
"should", so a conforming vendor could define their own operator
called e.g. "moz-saturate" (or called "over" if they had a good
reason) (according to that "should") but nobody would be able to ever
use it (according to the "must"s).

"strings should be parsed as CSS <color> values" - s/should/must/

The colour parsing refers to [CSS3COLOR]. No profile is described, so
presumably all of CSS3 Color should be supported. In that case: what
should "currentColor" do, since its CSS definition makes no sense
here? (By the way, after reading CSS3 Color, I can appreciate WA1's
writing style and the way that it doesn't have obvious errors and
omissions and ABC...)

"Immediately before the 0 offset and immediately after the 1 offset,
transparent black stops are be assumed." - syntax error, and should
have "must".

"Once a gradient has been created (see below), stops must be placed
along it to define how the colors are distributed along the gradient."
- is that meant to be "must"? (i.e. authors are non-conforming if they
don't specify any stops and use the all-transparent-black behaviour.)

"attribute DOMString shadowColor; // (default black)" - later it says
"transparent black".

"attribute DOMString globalCompositeOperation; // (default over)" -
later it says "source-over".


[1] http://canvex.lazyilluminati.com/tests/tests/
[2] http://canvex.lazyilluminati.com/tests/tests/index.2d.gradient.object.html
[3] http://canvex.lazyilluminati.com/tests/tests/2d.gradient.interpolate.outside.html
and http://canvex.lazyilluminati.com/misc/gradient/gradient2.html
[4] https://bugzilla.mozilla.org/show_bug.cgi?id=346017
[5] http://canvex.lazyilluminati.com/tests/tests/2d.gradient.interpolate.overlap.html
[6] http://ln.hixie.ch/?start=1140242962&count=1

Philip Taylor
excors at gmail.com

More information about the whatwg mailing list