The default bug view has changed. See this FAQ.

Transformations confuse canvas drawing with radial gradient fills

NEW
Unassigned

Status

()

Core
Canvas: 2D
7 years ago
6 years ago

People

(Reporter: Bjoern Hoehrmann, Unassigned)

Tracking

unspecified
Points:
---

Firefox Tracking Flags

(blocking2.0 -)

Details

Attachments

(3 attachments)

(Reporter)

Description

7 years ago
User-Agent:       Opera/9.80 (Windows NT 5.2; U; en) Presto/2.5.22 Version/10.51
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.2.6pre) Gecko/20100611 Namoroka/3.6.6pre

<canvas id='can' width='640' height='480'></canvas>
<script>
onload = function() {

  var ctx = document.getElementById('can').getContext('2d');
  var grd = ctx.createRadialGradient(50, 50, 0, 50, 50, 50);
  grd.addColorStop(0.0, 'rgba(0,0,0,0.5)');
  grd.addColorStop(1.0, 'rgba(0,0,0,0)');
  ctx.fillStyle = grd;

  for (var i = 0; i < 100; ++i) {
    var x = Math.random()*640 - 50;
    var y = Math.random()*480 - 50;
    ctx.translate(x, y);
    ctx.fillRect(0, 0, 100, 100);
    ctx.translate(-x, -y);
    // ctx.fillStyle = grd;
  }
}
</script>

The rendering changes dramatically depending on whether `ctx.fillStyle` is set in the loop or not; that however should have no effect.

Reproducible: Always
Indeed, seems like the rendering should be the one you see with the in-loop fillStyle.

vlad, do we need to DirtyAllStyles on transformation matrix changes or something?
Status: UNCONFIRMED → NEW
blocking2.0: --- → ?
Ever confirmed: true
We should fix this, but it doesn't block.
blocking2.0: ? → -

Comment 3

6 years ago
I also ran across a related bug in the following snippet.

    canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    
    ctx.transform(1,0,0,1,500,500);
    var grad = ctx.createRadialGradient(0,0,100,0,0,200);
    grad.addColorStop(0, 'red');
    grad.addColorStop(1, 'blue'); 
    ctx.fillStyle = grad;
//    ctx.fillRect(0,0,0,0); 
    ctx.transform(1,0,0,1,-500,-500);
    ctx.fillRect(300,300,400,400);

As it is, the gradient does not render properly, but when ctx.fillRect(0,0,0,0) is uncommented, then the gradient shows.

Comment 4

6 years ago
This behaves differently depending on platform, so this really should get fixed. Chris said the spec is not clear on this.

Updated

6 years ago
OS: Windows Server 2003 → All
Hardware: x86 → All
I was wrong about the spec: on second reading, I found "The points in the radial gradient must be transformed as described by the current transformation matrix when rendering."  D2D produces what I believe to be correct results on this test, solid-blue rect filled from <x=300,y=300>.

Comment 6

6 years ago
Shaon, can you attach a test case people can click on so we can try a few platforms?

Comment 7

6 years ago
Created attachment 544402 [details]
test case which exhibits strange behavior

the call to fillRect(0,0,0,0) causes the picture to render differently

Comment 8

6 years ago
Created attachment 544403 [details]
test case which exhibits strange behavior (extra fillRect added)

Comment 9

6 years ago
I get a solid blue rect on macosx with nightly and safari. On what platform is the output different?

Comment 10

6 years ago
Ah ok so D2D is wrong too Chris. I see the fill now with Nightly (with the extra fillRect). Safari shows a solid blue rect, so the hack doesn't seem to work there.

Comment 11

6 years ago
I am using Ubuntu. It shows with both the nightly build and Firefox 4.

Comment 12

6 years ago
No luck with macosx/chrome and macosx/opera either. Extra fillRect or not the result is a solid blue rect.
The solid blue rect is the correct rendering, if I'm reading the spec and test correctly.

My D2D nightly shows that on both tests, but I do see the gradient drawn in the second test in FF4.  That suggests a canvas/cairo or a cairo bug.  Will ask around today.
Some more notes
 - AFAICT from the spec, removing the transforms and fillRect(0,0,0,0) should result in the same behavior as leaving them all in.
 - In FF nightly: in all permutations of transforms/null-fill, only a solid blue box is drawn
 - In IE9: same
 - In FF5
   * with the transforms removed and null-fill or not, blue box
   * with transforms but no null-fill, blue box
   * with transforms and null-fill, gradient centered on <x=500,y=500>

I think we have a bug in the cairo canvas backend where we don't recreate the gradient pattern when the transform changes.  (Or don't create it lazily with the wrong transform.)  This may be a WONTFIX since the azure backend gets it right.
Created attachment 544867 [details] [diff] [review]
Test for bug 571708
You need to log in before you can comment on or make changes to this bug.