Closed Bug 478445 Opened 13 years ago Closed 11 years ago

canvas arc function produces different results when strokeText function is called afterward


(Core :: Canvas: 2D, defect, P1)




Tracking Status
blocking2.0 --- -


(Reporter: ap60, Assigned: bzbarsky)



(Keywords: testcase)


(3 files)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2

The arc function produces a different graphical result when the strokeText function is called afterward.

Reproducible: Always

Steps to Reproduce:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">

<html xmlns="">


<style type="text/css">
canvas { border: 2px solid red; }

<script type="text/javascript" language="JavaScript">

function main() {

   var canvas = document.getElementById('test');
   var ctx = canvas.getContext('2d');



   // strokeText seems to affect previous arc draw somehow in Firefox 3.1b2
   // The arc appears longer and fatter


function drawarc(ctx,x,y) {
   var radcvt=Math.PI/180;
   var ang=30;
   var rad=31; 



<div style="position:absolute;left:50px;top:50px">
<canvas id="test" width="1000" height="1000"></canvas>

<script type="text/javascript" language="JavaScript">


Actual Results:  
Three arcs are produced with the last one different than the first two.

Expected Results:  
Three arcs should be produced that are identical.
I can confirm that strokeText appears to also stroke a previously drawn arc, and possibly other paths.

I'm also seeing other odd behavior -- such as text shadows being clipped to a previously drawn arc, see this code snippet:

g.arc(150, 300, 200 + cycle * 100, 0, Math.PI*2, true);
var r = 200 + cycle * 100;
gradient = g.createRadialGradient( 150 - r * 0.25, 300 - r * 0.25, r * 0.25, 150, 300, r );
gradient.addColorStop( 0, hsv( t + 0.33, 0, 1 ) );
gradient.addColorStop( 0.4, hsv( t + 0.33, 1, 1 ) );
gradient.addColorStop( 0.9, hsv( t + 0.33, 1, 0.25 ) );
gradient.addColorStop( 1, hsv( t + 0.33, 1, 0.25, 0 ) );
g.fillStyle = gradient;

// Text is not supported in expcanvas!
if( g.font &amp;&amp; g.fillText ){
	g.shadowOffsetX = 1.0;
	g.shadowOffsetY = 3.0;
	g.shadowBlur = 3.0;
	g.shadowColor = hsv( 0, 0, 0, 1 );
	g.fillStyle = hsv( t, 1, 1, t );
	g.font = "32px Verdana";
	g.fillText( "Canvas Test", t * 600, 380 );
	g.strokeStyle = hsv( 0, 0, 1, 0.5 );
	g.shadowColor = "transparent black";
	g.strokeText( "Canvas", t * 600, 380 );

The complete example is available here:

Currently FF 4.5 is incorrectly drawing a white stroke around the shaded circle and clipping the text shadow to the circle.
I can confirm this behaviour as well.

context.strokeText() causes the previous path to be also drawn. If you do context.beginPath() then context.strokeText() and context.closePath() the problem is avoided.

Webkit does not require the use of beginPath() and closePath().
Attached file minimal test case
Minimal test case to show rendering bug with canvas stroke, the cross should have all arms the same length but differs when stroke() is called before or after closePath()
This is also verified with stroke in general,

created another testcase, verfied with: 3.7a1pre nightly on 10. september 2009.

Arms of the cross in the testcase should have same length but, are not the same if one is rendered with stroke called before closePath() and the other after closePath().
Also affects 3.6.2, Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20100316 Firefox/3.6.2 (.NET CLR 3.5.30729)
Also affects 

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv: Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
Problems with Firefox 3.5+, 4b.
(OK with Chrome.)

After a strokeText() the stokeStyle used to render the text will be also used
by the last displayed shape built with a beginPath.

1/ ctx.strokeStyle = "white";
2/ ctx.strokeText ("test",x,y);
3/ ctx.strokeStyle = "green";
4/ ctx.beginPath() ... ctx.arc (...) .... ctx.endPath(); ctx.stroke(); //
circle 1 => ok green
5/ ctx.strokeStyle = "blue";
6/ ctx.beginPath() ... ctx.arc (...) .... ctx.endPath(); ctx.stroke(); //
circle 2 => nok white

I can add a more complete example if needed.
A first workaround is to display an empty circle (size 0) at the end of the
rendering or to display the text only at the end. It's not clean at all.


In fact the problem occurs even if strokeText() is called at the end but the sequence
beginPath -> stokeText -> endPath works.
In fact the problem occurs even if strokeText() is called at the end but the sequence
beginPath -> stokeText -> endPath works.

Affects firefox 4.0b6 (Snow Leopard)
Component: General → Canvas: 2D
Keywords: testcase
Product: Firefox → Core
QA Contact: general → canvas.2d
Version: unspecified → Trunk
Assignee: nobody → bzbarsky
blocking2.0: --- → ?
Ever confirmed: true
OS: Windows XP → All
Priority: -- → P1
Hardware: x86 → All
Comment on attachment 493550 [details] [diff] [review]
strokeText needs to not re-stroke the current path.

This seems to do the trick, but do we need to do this earlier up where we do other bidi processing?  And do we need to do anything like this for the fill case?  I'm guessing no....
Attachment #493550 - Flags: review?(vladimir)
Whiteboard: [need review]
Comment on attachment 493550 [details] [diff] [review]
strokeText needs to not re-stroke the current path.

Looks right to me -- this might fix bug 499628 as well
Attachment #493550 - Flags: review?(vladimir)
Attachment #493550 - Flags: review+
Attachment #493550 - Flags: approval2.0+
Whiteboard: [need review] → [need landing]
> this might fix bug 499628 as well

Yeah, it does.
Blocks: 499628
This doesn't block, but it's got approval and should land.
blocking2.0: ? → -
Closed: 11 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
Whiteboard: [need landing]
Target Milestone: --- → mozilla2.0b8
Backed out the patch for being in the range of bug 615736
Resolution: FIXED → ---
Whiteboard: [need landing]

Tree is green.
Closed: 11 years ago11 years ago
Resolution: --- → FIXED
Whiteboard: [need landing]
You need to log in before you can comment on or make changes to this bug.