[whatwg] Canvas ath construction over save/restore boundaries

On Fri, 7 Mar 2008, Oliver Hunt wrote:
>
> Hi all, while working on a bug in our canvas implementation I've noticed 
> that there's a difference in behaviour between Opera and Firefox when 
> handling path construction over save/restore boundaries.  Section 
> 3.12.11.1.1 says that the canvas path is not part of the state that is 
> effected by save/restore, unfortunately Opera and Firefox disagree on 
> what this actually means.  Firefox appears to treat restore() 
> (effectively) as a transform that undoes the any transformations 
> performed in the current state, so given the example:
> 
> context.beginPath();
> context.save()
> context.translate(100,100)
> context.rect(0,0,10,10)
> context.restore()
> context.fill()
> 
> Firefox behaves as though the set of operations was
> 
> context.beginPath();
> context.translate(100,100)
> context.rect(0,0,10,10)
> context.translate(-100,-100)
> context.fill()
> 
> which, given 3.12.11.1.8., results in the fill operation still drawing a 
> 10x10 rect at (100,100).  Opera meanwhile treats the path as being 
> completely independent of the canvas state, and so draws the rect at 
> (0,0).
> 
> What I want to know is which behaviour the spec actually intends on 
> providing.

The current transformation matrix doesn't change the position at which the 
current path is filled. That is, assuming the fill style is a solid color, 
the following:

 context.beginPath();
 context.save()
 context.translate(100,100)
 context.rect(0,0,10,10)
 context.restore()
 context.fill()

...must render the same as:

 context.beginPath();
 context.save()
 context.translate(100,100)
 context.rect(0,0,10,10)
 //context.restore()
 context.fill()

Similarly the following:

 context.beginPath();
 context.translate(100,100)
 context.rect(0,0,10,10)
 context.translate(-100,-100)
 context.fill()

...must render the same as:

 context.beginPath();
 context.translate(100,100)
 context.rect(0,0,10,10)
 //context.translate(-100,-100)
 context.fill()

Thus the two examples you give must both render the same as:

 context.beginPath();
 context.translate(100,100)
 context.rect(0,0,10,10)
 context.fill()

...which is the same as:

 context.beginPath();
 context.rect(100,100,10,10)
 context.fill()

...which is the same as:

 context.fillRect(100,100,10,10)

...so Opera is wrong.

HTH,
-- 
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

Received on Thursday, 12 June 2008 15:47:19 UTC