Bug 1860763. Expand workaround for d2d arcs that are full circles slightly. r=gfx-reviewers,lsalzman

The other check for (close to) full circle arcs lower down in this function

https://searchfox.org/mozilla-central/rev/01a0d864a9442d0fe2dbd4beee5c88b9b46e96bd/gfx/2d/PathD2D.cpp#221

does not catch the testcase from this bug: the start and end points are just barely far enough away.

It only makes sense that if we are changing all arcs >= 2*Pi to 1.9999*Pi that we should also change arcs between 1.9999*Pi and 2*Pi, and that fixes this bug.

I also added some instructions to the wpt canvas tests gentest.py file, which I didn't find anywhere else.

Differential Revision: https://phabricator.services.mozilla.com/D192414
This commit is contained in:
Timothy Nikkel 2023-11-01 04:05:29 +00:00
parent 197de3d0a2
commit 11d085b63c
9 changed files with 236 additions and 2 deletions

View File

@ -188,10 +188,10 @@ void PathBuilderD2D::Arc(const Point& aOrigin, Float aRadius, Float aStartAngle,
// XXX - Workaround for now, D2D does not appear to do the desired thing when
// the angle sweeps a complete circle.
bool fullCircle = false;
if (aEndAngle - aStartAngle >= 2 * M_PI) {
if (aEndAngle - aStartAngle >= 1.9999 * M_PI) {
fullCircle = true;
aEndAngle = Float(aStartAngle + M_PI * 1.9999);
} else if (aStartAngle - aEndAngle >= 2 * M_PI) {
} else if (aStartAngle - aEndAngle >= 1.9999 * M_PI) {
fullCircle = true;
aStartAngle = Float(aEndAngle + M_PI * 1.9999);
}

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<title>Canvas test: 2d.path.arc.twopie.5</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/html/canvas/resources/canvas-tests.js"></script>
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
<body class="show_output">
<h1>2d.path.arc.twopie.5</h1>
<p class="desc">arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise</p>
<p class="output">Actual output:</p>
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<ul id="d"></ul>
<script>
var t = async_test("arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise");
_addTest(function(canvas, ctx) {
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.arc(50, 25, 50, 2, 2 + 2*Math.PI, false);
ctx.closePath();
ctx.fill();
_assertPixel(canvas, 95,25, 0,0,0,255);
});
</script>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<title>Canvas test: 2d.path.arc.twopie.6</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/html/canvas/resources/canvas-tests.js"></script>
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
<body class="show_output">
<h1>2d.path.arc.twopie.6</h1>
<p class="desc">arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise</p>
<p class="output">Actual output:</p>
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<ul id="d"></ul>
<script>
var t = async_test("arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise");
_addTest(function(canvas, ctx) {
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.arc(50, 25, 50, 5, 5 + 2*Math.PI, false);
ctx.closePath();
ctx.fill();
_assertPixel(canvas, 5,25, 0,0,0,255);
});
</script>

View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<title>OffscreenCanvas test: 2d.path.arc.twopie.5</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/html/canvas/resources/canvas-tests.js"></script>
<h1>2d.path.arc.twopie.5</h1>
<p class="desc">arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise</p>
<script>
var t = async_test("arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise");
var t_pass = t.done.bind(t);
var t_fail = t.step_func(function(reason) {
throw reason;
});
t.step(function() {
var canvas = new OffscreenCanvas(100, 50);
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.arc(50, 25, 50, 2, 2 + 2*Math.PI, false);
ctx.closePath();
ctx.fill();
_assertPixel(canvas, 95,25, 0,0,0,255);
t.done();
});
</script>

View File

@ -0,0 +1,30 @@
// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
// OffscreenCanvas test in a worker:2d.path.arc.twopie.5
// Description:arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise
// Note:
importScripts("/resources/testharness.js");
importScripts("/html/canvas/resources/canvas-tests.js");
var t = async_test("arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise");
var t_pass = t.done.bind(t);
var t_fail = t.step_func(function(reason) {
throw reason;
});
t.step(function() {
var canvas = new OffscreenCanvas(100, 50);
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.arc(50, 25, 50, 2, 2 + 2*Math.PI, false);
ctx.closePath();
ctx.fill();
_assertPixel(canvas, 95,25, 0,0,0,255);
t.done();
});
done();

View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<title>OffscreenCanvas test: 2d.path.arc.twopie.6</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/html/canvas/resources/canvas-tests.js"></script>
<h1>2d.path.arc.twopie.6</h1>
<p class="desc">arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise</p>
<script>
var t = async_test("arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise");
var t_pass = t.done.bind(t);
var t_fail = t.step_func(function(reason) {
throw reason;
});
t.step(function() {
var canvas = new OffscreenCanvas(100, 50);
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.arc(50, 25, 50, 5, 5 + 2*Math.PI, false);
ctx.closePath();
ctx.fill();
_assertPixel(canvas, 5,25, 0,0,0,255);
t.done();
});
</script>

View File

@ -0,0 +1,30 @@
// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
// OffscreenCanvas test in a worker:2d.path.arc.twopie.6
// Description:arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise
// Note:
importScripts("/resources/testharness.js");
importScripts("/html/canvas/resources/canvas-tests.js");
var t = async_test("arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise");
var t_pass = t.done.bind(t);
var t_fail = t.step_func(function(reason) {
throw reason;
});
t.step(function() {
var canvas = new OffscreenCanvas(100, 50);
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.arc(50, 25, 50, 5, 5 + 2*Math.PI, false);
ctx.closePath();
ctx.fill();
_assertPixel(canvas, 5,25, 0,0,0,255);
t.done();
});
done();

View File

@ -1,3 +1,13 @@
# To use this script:
# -make a python virtual environment somewhere (it doesn't matter where)
# python3 -m venv venv
# -enter the virtual environment
# source venv/bin/activate
# -install required packages in the venv
# pip3 install cairocffi jinja2 pyyaml
# -change to the directory with this script and run it
# python3 gentest.py
from gentestutils import genTestUtils
from gentestutilsunion import genTestUtils_union

View File

@ -966,6 +966,32 @@
@assert pixel 50,20 == 0,255,0,255;
expected: green
- name: 2d.path.arc.twopie.5
desc: arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise
code: |
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.arc(50, 25, 50, 2, 2 + 2*Math.PI, false);
ctx.closePath();
ctx.fill();
@assert pixel 95,25 == 0,0,0,255;
- name: 2d.path.arc.twopie.6
desc: arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise
code: |
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.arc(50, 25, 50, 5, 5 + 2*Math.PI, false);
ctx.closePath();
ctx.fill();
@assert pixel 5,25 == 0,0,0,255;
- name: 2d.path.arc.shape.1
desc: arc() from 0 to pi does not draw anything in the wrong half
code: |