[whatwg] Canvas "coordinate space units"

David Flanagan david at davidflanagan.com
Wed Jul 14 17:29:43 PDT 2010

Aryeh Gregor wrote:
> On Wed, Jul 14, 2010 at 3:03 PM, David Flanagan <david at davidflanagan.com> wrote:
>> I'm confused by the term "coordinate space units" as applied to the canvas
>> spec.  It does not seem to be defined.
> It seems clear to me.  

Even if clear, it is still undefined.  And the words "coordinate space" 
are so generic as to be meaningless here.  "canvas units" or something 
would make more sense.

The 2D context represents a Cartesian plane,
> and the units for everything are units within that plane.  One
> coordinate space unit might correspond to any number of pixels,
> depending:
> """
> The intrinsic dimensions of the canvas element equal the size of the
> coordinate space, with the numbers interpreted in CSS pixels. However,
> the element can be sized arbitrarily by a style sheet. During
> rendering, the image is scaled to fit this layout size.
> The size of the coordinate space does not necessarily represent the
> size of the actual bitmap that the user agent will use internally or
> during rendering. On high-definition displays, for instance, the user
> agent may internally use a bitmap with two device pixels per unit in
> the coordinate space, so that the rendering remains at high quality
> throughout.
> """

As an aside, do you think any implementations actually do that?  It 
seems to me that it would cause real problems with drawImage(): images 
would look bad compared to drawn graphics...

>> It is used in the definition of the translate() method, for example, and
>> seems to imply that coordinate space units are affected by scale()
>> operations.
> The transformation matrix is referred to in a particular well-defined
> way by some methods.  For instance, the rectangle methods say:
> """
> The current transformation matrix must be applied to the following
> four coordinates, which form the path that must then be closed to get
> the specified rectangle: (x, y), (x+w, y), (x+w, y+h), (x, y+h).
> """
> This only affects operations where it says so explicitly.  Nothing
> that I see says it affects the coordinate space units themselves (if
> that even makes sense).

Okay; that makes sense.  Points passed to path definition methods are 
transformed according to the CTM.  I tend to think of transformations as 
affecting the entire coordinate space. But the spec is written with only 
one coordinate space defined, and points are transformed to this space 
as they are added to the path.

>> It is used in the definition of the lineWidth attribute as well. Chrome,
>> Firefox and Opera all scaled lineWidth and Phillip Taylor's test suite
>> expects this behavior as well.
> I can't find where it says lineWidth should be scaled . . .

It doesn't. But all implementations do it, as you pretty much be 
expected (otherwise drawings wouldn't scale right). The spec does not 
actually define what it means to stroke a line.  If it did, it would 
probably have to say something like this:

1) Transform all the points in the path using the inverse of the CTM to 
convert them from the canvas coordinate space to the current user 
coordinate space (or some such language).

2) Define rectangles around each straight line segment of the path, 
where each rectangle is lineWidth pixels wide, and connect these 
rectangles with caps, miters and so on.  (this is the part that would be 
a pain to spec, I think)  So now the path has been transformed into a 
set of polygons.

3) Transform those polygons back to the canvas coordinate space using 
the CTM and fill them.

I'm not trying to suggest that the spec needs to be modified to 
explicitly define how to stroke lines.  But without an explanation of 
the process, the handling of lineWidth is difficult to explain. 
Certainly just saying that lineWidth is measured in coordinate space 
units is not sufficient.  To me, it seems to imply that line width 
should never scale, and I don't think that is intended.


>> But then in the definition of shadowOffsetX and Y, the spec reads:
>>> Their values are in coordinate space units. They are not affected by the
>>> current transformation matrix.
>> The description of isPointInPath() uses similar language:
>>>  when treated as coordinates in the canvas coordinate space unaffected by
>>> the current transformation,
>> So which is it?  Are "coordinate space units" affected by scaling or not?
> As far as I can tell, no.  When the transformation matrix is used, it
> says so explicitly.  The language you point to for shadowOffset and
> isPointInPath is just a reminder.  I think.
>>  Are lineWidths supposed to be scaled? (Implementations do so consistently)
> I don't think they're supposed to be from reading the spec, although I
> don't know why not.  Maybe I'm missing something, or maybe this needs
> to be clarified.
>> Are shadow offset supposed to be scaled? (Chrome does, Firefox and Opera do
>> not)
> Doesn't it say explicitly that they shouldn't be?
>> I think a clearer definition of coordinate spaces would be helpful. Maybe
>> "device space" for the underlying pixmap, "canvas space" for the coordinates
>> defined by the width and height attributes of the canvas, and "user space"
>> for the space defined by the current transformation matrix?
> It might be a good idea to separate out the units for stuff affected
> by transformations vs. not, yeah.  I don't know why anything shouldn't
> be transformed by the current transformation matrix, though.

More information about the whatwg mailing list