Bug 105650

Summary: Quadratic and bezier curves with coincident endpoints rendered incorrectly
Product: WebKit Reporter: Kenneth Russell <kbr>
Component: CanvasAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: buildbot, dino, gyuyoung.kim, junov, ojan.autocc, rakuco, rniwa, senorblanco, simon.fraser, thorton, webkit.review.bot, youennf
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: All   
OS: All   
Bug Depends on:    
Bug Blocks: 107118    
Attachments:
Description Flags
Test case
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch none

Description Kenneth Russell 2012-12-21 12:13:05 PST
CanvasRenderingContext2D::quadraticCurveTo and bezierCurveTo contain incorrect optimizations which skip adding the incoming curve if its endpoint is the same as the path's current point. It is easy to construct a Bezier curve with coincident endpoints and non-zero area by moving its control points; similarly, a degenerate quadratic curve with coincident endpoints but a different control point should be rendered as a line. The attached test case from https://code.google.com/p/chromium/issues/detail?id=160277 shows the problem for bezier curves, but the same problem exists for quadratic curves.
Comment 1 Kenneth Russell 2012-12-21 12:14:15 PST
Created attachment 180544 [details]
Test case
Comment 2 youenn fablet 2013-01-07 08:36:46 PST
I came across this bug description when searching for a potential bug related to CanvasRenderingContext2D::arcTo.
If that is not already done, I can propose a patch fixing this bug and adding corresponding test cases. Probably the test cases could follow the style of the current canvas test suite, something like a green rectangle generation:

<canvas id="myCanvas" width="100" height="50">
</canvas>
<script>
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.bezierCurveTo(100, 0, 0, 50, 0, 0);
ctx.lineWidth = 150;
ctx.strokeStyle = '#0f0';
ctx.stroke();
</script>
Comment 3 Kenneth Russell 2013-01-07 12:29:20 PST
(In reply to comment #2)
> I came across this bug description when searching for a potential bug related to CanvasRenderingContext2D::arcTo.
> If that is not already done, I can propose a patch fixing this bug and adding corresponding test cases. Probably the test cases could follow the style of the current canvas test suite, something like a green rectangle generation:
> 
> <canvas id="myCanvas" width="100" height="50">
> </canvas>
> <script>
> var canvas = document.getElementById('myCanvas');
> var ctx = canvas.getContext('2d');
> ctx.beginPath();
> ctx.moveTo(0, 0);
> ctx.bezierCurveTo(100, 0, 0, 50, 0, 0);
> ctx.lineWidth = 150;
> ctx.strokeStyle = '#0f0';
> ctx.stroke();
> </script>

It would be great if you would propose a patch and tests. Nobody has taken this bug yet.

I think it would be best if you could write the tests using getImageData() and verifying that a couple of pixels are rendered a certain color, or at all, rather than as pixel tests. That way the precise antialiasing algorithm for curve rendering won't affect the test results.
Comment 4 youenn fablet 2013-01-08 08:08:20 PST
(In reply to comment #3)
Ok, I will study it in the coming days.
Comment 5 youenn fablet 2013-01-10 08:05:50 PST
Created attachment 182139 [details]
Patch
Comment 6 Stephen White 2013-01-10 10:09:49 PST
Comment on attachment 182139 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=182139&action=review

> LayoutTests/ChangeLog:11
> +        * fast/canvas/canvas-bezier-same-endpoint-expected.txt: Added.
> +        * fast/canvas/canvas-bezier-same-endpoint.html: Added.
> +        * fast/canvas/canvas-quadratic-same-endpoint-expected.txt: Added.
> +        * fast/canvas/canvas-quadratic-same-endpoint.html: Added.

Looks like these files didn't get attached to the patch.
Comment 7 Benjamin Poulain 2013-01-10 14:33:12 PST
Comment on attachment 182139 [details]
Patch

You forgot to attach the new tests and expectations.
Comment 8 youenn fablet 2013-01-11 03:07:10 PST
Created attachment 182310 [details]
Patch
Comment 9 youenn fablet 2013-01-11 03:11:51 PST
New patch with all files this time.
The tests are working with my local WebKit-Qt.
One test is failing with my local WebKit-EFL, I will investigate this further.
Comment 10 Build Bot 2013-01-11 03:35:15 PST
Comment on attachment 182310 [details]
Patch

Attachment 182310 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/15815142

New failing tests:
fast/canvas/canvas-quadratic-same-endpoint.html
Comment 11 Kenneth Russell 2013-01-11 10:41:23 PST
Comment on attachment 182310 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=182310&action=review

Thanks for the tests. They need a little more work and a clean EWS run.

> LayoutTests/fast/canvas/canvas-bezier-same-endpoint.html:39
> +shouldBeBlue(70,70);

Per the other test below, I think sampling exactly on the line / degenerate curve is too fragile. I think you should sample a few pixels which cross the line, and assert that at least one of them was actually drawn (i.e., wasn't the background color).

> LayoutTests/fast/canvas/canvas-bezier-same-endpoint.html:45
> +shouldBeBlue(75,75);

Same here.

> LayoutTests/fast/canvas/canvas-bezier-same-endpoint.html:49
> +ctx.stroke();

Please test filling of a curve as well as stroking. A degenerate bezier can cover significant area so you can sample the interior in a few places and ensure it was drawn.

> LayoutTests/fast/canvas/canvas-quadratic-same-endpoint.html:37
> +shouldBeYellow(50,50);

Because this test is failing on Mac it looks like it is too fragile. I think you should sample a few pixels which cross the degenerate curve, and assert that at least one was drawn (i.e., wasn't the background color). Also, please test filling as well as stroking the path.
Comment 12 youenn fablet 2013-01-18 04:37:32 PST
I opened a new bug (https://bugs.webkit.org/show_bug.cgi?id=107118), as the uploaded patch seems to uncover potential issues with back end graphic libraries (such as Qt and cairo) in the rendering of quad curves with same endpoints.

I will increase the lineWidth within the tests to strengthen the tests.
I will update TestExpectations so that mac ews runs fine.
Comment 13 youenn fablet 2013-01-24 05:21:46 PST
Created attachment 184468 [details]
Patch
Comment 14 youenn fablet 2013-01-24 07:55:01 PST
Created attachment 184493 [details]
Patch
Comment 15 youenn fablet 2013-01-25 06:20:13 PST
Created attachment 184738 [details]
Patch
Comment 16 youenn fablet 2013-01-25 07:26:12 PST
Created attachment 184748 [details]
Patch
Comment 17 Kenneth Russell 2013-01-25 10:21:03 PST
Comment on attachment 184748 [details]
Patch

Very nice. Thanks for persisting with this patch. Did you want this submitted to the commit queue? Mark cq? in Patch Details if so.
Comment 18 WebKit Review Bot 2013-01-31 15:53:31 PST
Comment on attachment 184748 [details]
Patch

Clearing flags on attachment: 184748

Committed r141500: <http://trac.webkit.org/changeset/141500>
Comment 19 WebKit Review Bot 2013-01-31 15:53:37 PST
All reviewed patches have been landed.  Closing bug.