Best JavaScript code snippet using wpt
path-objects.js
Source:path-objects.js
...43 } else {44 assert.strictEqual(actual, expected);45 }46}47function _assertPixel(canvas, x, y, r, g, b, a, pos, color) {48 const c = _getPixel(canvas, x,y);49 assert.strictEqual(c[0], r, 'Red channel of the pixel at (' + x + ', ' + y + ')');50 assert.strictEqual(c[1], g, 'Green channel of the pixel at (' + x + ', ' + y + ')');51 assert.strictEqual(c[2], b, 'Blue channel of the pixel at (' + x + ', ' + y + ')');52 assert.strictEqual(c[3], a, 'Alpha channel of the pixel at (' + x + ', ' + y + ')');53}54function _assertPixelApprox(canvas, x, y, r, g, b, a, pos, color, tolerance) {55 const c = _getPixel(canvas, x,y);56 _assertApprox(c[0], r, tolerance, 'Red channel of the pixel at (' + x + ', ' + y + ')');57 _assertApprox(c[1], g, tolerance, 'Green channel of the pixel at (' + x + ', ' + y + ')');58 _assertApprox(c[2], b, tolerance, 'Blue channel of the pixel at (' + x + ', ' + y + ')');59 _assertApprox(c[3], a, tolerance, 'Alpha channel of the pixel at (' + x + ', ' + y + ')');60}61function assert_throws_js(Type, fn) {62 assert.throws(fn, Type);63}64// Used by font tests to allow fonts to load.65function deferTest() {}66class Test {67 // Two cases of this in the tests, look unnecessary.68 done() {}69 // Used by font tests to allow fonts to load.70 step_func_done(func) { func(); }71 // Used for image onload callback.72 step_func(func) { func(); }73}74function step_timeout(result, time) {75 // Nothing; code needs to be converted for this to work.76}77describe("WPT: path-objects", function () {78 it("2d.path.initial", function () {79 const canvas = createCanvas(100, 50);80 const ctx = canvas.getContext("2d");81 const t = new Test();82 ctx.fillStyle = '#0f0';83 ctx.fillRect(0, 0, 100, 50);84 ctx.closePath();85 ctx.fillStyle = '#f00';86 ctx.fill();87 _assertPixel(canvas, 50,25, 0,255,0,255);88 });89 it("2d.path.beginPath", function () {90 const canvas = createCanvas(100, 50);91 const ctx = canvas.getContext("2d");92 const t = new Test();93 ctx.fillStyle = '#0f0';94 ctx.fillRect(0, 0, 100, 50);95 ctx.rect(0, 0, 100, 50);96 ctx.beginPath();97 ctx.fillStyle = '#f00';98 ctx.fill();99 _assertPixel(canvas, 50,25, 0,255,0,255);100 });101 it("2d.path.moveTo.basic", function () {102 const canvas = createCanvas(100, 50);103 const ctx = canvas.getContext("2d");104 const t = new Test();105 ctx.fillStyle = '#f00';106 ctx.fillRect(0, 0, 100, 50);107 ctx.rect(0, 0, 10, 50);108 ctx.moveTo(100, 0);109 ctx.lineTo(10, 0);110 ctx.lineTo(10, 50);111 ctx.lineTo(100, 50);112 ctx.fillStyle = '#0f0';113 ctx.fill();114 _assertPixel(canvas, 90,25, 0,255,0,255);115 });116 it("2d.path.moveTo.newsubpath", function () {117 const canvas = createCanvas(100, 50);118 const ctx = canvas.getContext("2d");119 const t = new Test();120 ctx.fillStyle = '#0f0';121 ctx.fillRect(0, 0, 100, 50);122 ctx.beginPath();123 ctx.moveTo(0, 0);124 ctx.moveTo(100, 0);125 ctx.moveTo(100, 50);126 ctx.moveTo(0, 50);127 ctx.fillStyle = '#f00';128 ctx.fill();129 _assertPixel(canvas, 50,25, 0,255,0,255);130 });131 it("2d.path.moveTo.multiple", function () {132 const canvas = createCanvas(100, 50);133 const ctx = canvas.getContext("2d");134 const t = new Test();135 ctx.fillStyle = '#f00';136 ctx.fillRect(0, 0, 100, 50);137 ctx.moveTo(0, 25);138 ctx.moveTo(100, 25);139 ctx.moveTo(0, 25);140 ctx.lineTo(100, 25);141 ctx.strokeStyle = '#0f0';142 ctx.lineWidth = 50;143 ctx.stroke();144 _assertPixel(canvas, 50,25, 0,255,0,255);145 });146 it("2d.path.moveTo.nonfinite", function () {147 // moveTo() with Infinity/NaN is ignored148 const canvas = createCanvas(100, 50);149 const ctx = canvas.getContext("2d");150 const t = new Test();151 ctx.moveTo(0, 0);152 ctx.lineTo(100, 0);153 ctx.moveTo(Infinity, 50);154 ctx.moveTo(-Infinity, 50);155 ctx.moveTo(NaN, 50);156 ctx.moveTo(0, Infinity);157 ctx.moveTo(0, -Infinity);158 ctx.moveTo(0, NaN);159 ctx.moveTo(Infinity, Infinity);160 ctx.lineTo(100, 50);161 ctx.lineTo(0, 50);162 ctx.fillStyle = '#0f0';163 ctx.fill();164 _assertPixel(canvas, 50,25, 0,255,0,255);165 });166 it("2d.path.closePath.empty", function () {167 const canvas = createCanvas(100, 50);168 const ctx = canvas.getContext("2d");169 const t = new Test();170 ctx.fillStyle = '#0f0';171 ctx.fillRect(0, 0, 100, 50);172 ctx.closePath();173 ctx.fillStyle = '#f00';174 ctx.fill();175 _assertPixel(canvas, 50,25, 0,255,0,255);176 });177 it("2d.path.closePath.newline", function () {178 const canvas = createCanvas(100, 50);179 const ctx = canvas.getContext("2d");180 const t = new Test();181 ctx.fillStyle = '#f00';182 ctx.fillRect(0, 0, 100, 50);183 ctx.strokeStyle = '#0f0';184 ctx.lineWidth = 50;185 ctx.moveTo(-100, 25);186 ctx.lineTo(-100, -100);187 ctx.lineTo(200, -100);188 ctx.lineTo(200, 25);189 ctx.closePath();190 ctx.stroke();191 _assertPixel(canvas, 50,25, 0,255,0,255);192 });193 it("2d.path.closePath.nextpoint", function () {194 const canvas = createCanvas(100, 50);195 const ctx = canvas.getContext("2d");196 const t = new Test();197 ctx.fillStyle = '#f00';198 ctx.fillRect(0, 0, 100, 50);199 ctx.strokeStyle = '#0f0';200 ctx.lineWidth = 50;201 ctx.moveTo(-100, 25);202 ctx.lineTo(-100, -1000);203 ctx.closePath();204 ctx.lineTo(1000, 25);205 ctx.stroke();206 _assertPixel(canvas, 50,25, 0,255,0,255);207 });208 it("2d.path.lineTo.ensuresubpath.1", function () {209 // If there is no subpath, the point is added and nothing is drawn210 const canvas = createCanvas(100, 50);211 const ctx = canvas.getContext("2d");212 const t = new Test();213 ctx.fillStyle = '#0f0';214 ctx.fillRect(0, 0, 100, 50);215 ctx.strokeStyle = '#f00';216 ctx.lineWidth = 50;217 ctx.beginPath();218 ctx.lineTo(100, 50);219 ctx.stroke();220 _assertPixel(canvas, 50,25, 0,255,0,255);221 });222 it("2d.path.lineTo.ensuresubpath.2", function () {223 // If there is no subpath, the point is added and used for subsequent drawing224 const canvas = createCanvas(100, 50);225 const ctx = canvas.getContext("2d");226 const t = new Test();227 ctx.fillStyle = '#f00';228 ctx.fillRect(0, 0, 100, 50);229 ctx.strokeStyle = '#0f0';230 ctx.lineWidth = 50;231 ctx.beginPath();232 ctx.lineTo(0, 25);233 ctx.lineTo(100, 25);234 ctx.stroke();235 _assertPixel(canvas, 50,25, 0,255,0,255);236 });237 it("2d.path.lineTo.basic", function () {238 const canvas = createCanvas(100, 50);239 const ctx = canvas.getContext("2d");240 const t = new Test();241 ctx.fillStyle = '#f00';242 ctx.fillRect(0, 0, 100, 50);243 ctx.strokeStyle = '#0f0';244 ctx.lineWidth = 50;245 ctx.beginPath();246 ctx.moveTo(0, 25);247 ctx.lineTo(100, 25);248 ctx.stroke();249 _assertPixel(canvas, 50,25, 0,255,0,255);250 });251 it("2d.path.lineTo.nextpoint", function () {252 const canvas = createCanvas(100, 50);253 const ctx = canvas.getContext("2d");254 const t = new Test();255 ctx.fillStyle = '#f00';256 ctx.fillRect(0, 0, 100, 50);257 ctx.strokeStyle = '#0f0';258 ctx.lineWidth = 50;259 ctx.beginPath();260 ctx.moveTo(-100, -100);261 ctx.lineTo(0, 25);262 ctx.lineTo(100, 25);263 ctx.stroke();264 _assertPixel(canvas, 50,25, 0,255,0,255);265 });266 it("2d.path.lineTo.nonfinite", function () {267 // lineTo() with Infinity/NaN is ignored268 const canvas = createCanvas(100, 50);269 const ctx = canvas.getContext("2d");270 const t = new Test();271 ctx.moveTo(0, 0);272 ctx.lineTo(100, 0);273 ctx.lineTo(Infinity, 50);274 ctx.lineTo(-Infinity, 50);275 ctx.lineTo(NaN, 50);276 ctx.lineTo(0, Infinity);277 ctx.lineTo(0, -Infinity);278 ctx.lineTo(0, NaN);279 ctx.lineTo(Infinity, Infinity);280 ctx.lineTo(100, 50);281 ctx.lineTo(0, 50);282 ctx.fillStyle = '#0f0';283 ctx.fill();284 _assertPixel(canvas, 50,25, 0,255,0,255);285 _assertPixel(canvas, 90,45, 0,255,0,255);286 });287 it("2d.path.lineTo.nonfinite.details", function () {288 // lineTo() with Infinity/NaN for first arg still converts the second arg289 const canvas = createCanvas(100, 50);290 const ctx = canvas.getContext("2d");291 const t = new Test();292 for (var arg1 of [Infinity, -Infinity, NaN]) {293 var converted = false;294 ctx.lineTo(arg1, { valueOf: function() { converted = true; return 0; } });295 assert(converted, "converted");296 }297 });298 it("2d.path.quadraticCurveTo.ensuresubpath.1", function () {299 // If there is no subpath, the first control point is added (and nothing is drawn up to it)300 const canvas = createCanvas(100, 50);301 const ctx = canvas.getContext("2d");302 const t = new Test();303 ctx.fillStyle = '#0f0';304 ctx.fillRect(0, 0, 100, 50);305 ctx.strokeStyle = '#f00';306 ctx.lineWidth = 50;307 ctx.beginPath();308 ctx.quadraticCurveTo(100, 50, 200, 50);309 ctx.stroke();310 _assertPixel(canvas, 50,25, 0,255,0,255);311 _assertPixel(canvas, 95,45, 0,255,0,255);312 });313 it("2d.path.quadraticCurveTo.ensuresubpath.2", function () {314 // If there is no subpath, the first control point is added315 const canvas = createCanvas(100, 50);316 const ctx = canvas.getContext("2d");317 const t = new Test();318 ctx.fillStyle = '#f00';319 ctx.fillRect(0, 0, 100, 50);320 ctx.strokeStyle = '#0f0';321 ctx.lineWidth = 50;322 ctx.beginPath();323 ctx.quadraticCurveTo(0, 25, 100, 25);324 ctx.stroke();325 _assertPixel(canvas, 50,25, 0,255,0,255);326 _assertPixel(canvas, 5,45, 0,255,0,255);327 });328 it("2d.path.quadraticCurveTo.basic", function () {329 const canvas = createCanvas(100, 50);330 const ctx = canvas.getContext("2d");331 const t = new Test();332 ctx.fillStyle = '#f00';333 ctx.fillRect(0, 0, 100, 50);334 ctx.strokeStyle = '#0f0';335 ctx.lineWidth = 50;336 ctx.beginPath();337 ctx.moveTo(0, 25);338 ctx.quadraticCurveTo(100, 25, 100, 25);339 ctx.stroke();340 _assertPixel(canvas, 50,25, 0,255,0,255);341 });342 it("2d.path.quadraticCurveTo.shape", function () {343 const canvas = createCanvas(100, 50);344 const ctx = canvas.getContext("2d");345 const t = new Test();346 ctx.fillStyle = '#f00';347 ctx.fillRect(0, 0, 100, 50);348 ctx.strokeStyle = '#0f0';349 ctx.lineWidth = 55;350 ctx.beginPath();351 ctx.moveTo(-1000, 1050);352 ctx.quadraticCurveTo(0, -1000, 1200, 1050);353 ctx.stroke();354 _assertPixel(canvas, 50,25, 0,255,0,255);355 _assertPixel(canvas, 1,1, 0,255,0,255);356 _assertPixel(canvas, 98,1, 0,255,0,255);357 _assertPixel(canvas, 1,48, 0,255,0,255);358 _assertPixel(canvas, 98,48, 0,255,0,255);359 });360 it("2d.path.quadraticCurveTo.scaled", function () {361 const canvas = createCanvas(100, 50);362 const ctx = canvas.getContext("2d");363 const t = new Test();364 ctx.fillStyle = '#f00';365 ctx.fillRect(0, 0, 100, 50);366 ctx.scale(1000, 1000);367 ctx.strokeStyle = '#0f0';368 ctx.lineWidth = 0.055;369 ctx.beginPath();370 ctx.moveTo(-1, 1.05);371 ctx.quadraticCurveTo(0, -1, 1.2, 1.05);372 ctx.stroke();373 _assertPixel(canvas, 50,25, 0,255,0,255);374 _assertPixel(canvas, 1,1, 0,255,0,255);375 _assertPixel(canvas, 98,1, 0,255,0,255);376 _assertPixel(canvas, 1,48, 0,255,0,255);377 _assertPixel(canvas, 98,48, 0,255,0,255);378 });379 it("2d.path.quadraticCurveTo.nonfinite", function () {380 // quadraticCurveTo() with Infinity/NaN is ignored381 const canvas = createCanvas(100, 50);382 const ctx = canvas.getContext("2d");383 const t = new Test();384 ctx.moveTo(0, 0);385 ctx.lineTo(100, 0);386 ctx.quadraticCurveTo(Infinity, 50, 0, 50);387 ctx.quadraticCurveTo(-Infinity, 50, 0, 50);388 ctx.quadraticCurveTo(NaN, 50, 0, 50);389 ctx.quadraticCurveTo(0, Infinity, 0, 50);390 ctx.quadraticCurveTo(0, -Infinity, 0, 50);391 ctx.quadraticCurveTo(0, NaN, 0, 50);392 ctx.quadraticCurveTo(0, 50, Infinity, 50);393 ctx.quadraticCurveTo(0, 50, -Infinity, 50);394 ctx.quadraticCurveTo(0, 50, NaN, 50);395 ctx.quadraticCurveTo(0, 50, 0, Infinity);396 ctx.quadraticCurveTo(0, 50, 0, -Infinity);397 ctx.quadraticCurveTo(0, 50, 0, NaN);398 ctx.quadraticCurveTo(Infinity, Infinity, 0, 50);399 ctx.quadraticCurveTo(Infinity, Infinity, Infinity, 50);400 ctx.quadraticCurveTo(Infinity, Infinity, Infinity, Infinity);401 ctx.quadraticCurveTo(Infinity, Infinity, 0, Infinity);402 ctx.quadraticCurveTo(Infinity, 50, Infinity, 50);403 ctx.quadraticCurveTo(Infinity, 50, Infinity, Infinity);404 ctx.quadraticCurveTo(Infinity, 50, 0, Infinity);405 ctx.quadraticCurveTo(0, Infinity, Infinity, 50);406 ctx.quadraticCurveTo(0, Infinity, Infinity, Infinity);407 ctx.quadraticCurveTo(0, Infinity, 0, Infinity);408 ctx.quadraticCurveTo(0, 50, Infinity, Infinity);409 ctx.lineTo(100, 50);410 ctx.lineTo(0, 50);411 ctx.fillStyle = '#0f0';412 ctx.fill();413 _assertPixel(canvas, 50,25, 0,255,0,255);414 _assertPixel(canvas, 90,45, 0,255,0,255);415 });416 it("2d.path.bezierCurveTo.ensuresubpath.1", function () {417 // If there is no subpath, the first control point is added (and nothing is drawn up to it)418 const canvas = createCanvas(100, 50);419 const ctx = canvas.getContext("2d");420 const t = new Test();421 ctx.fillStyle = '#0f0';422 ctx.fillRect(0, 0, 100, 50);423 ctx.strokeStyle = '#f00';424 ctx.lineWidth = 50;425 ctx.beginPath();426 ctx.bezierCurveTo(100, 50, 200, 50, 200, 50);427 ctx.stroke();428 _assertPixel(canvas, 50,25, 0,255,0,255);429 _assertPixel(canvas, 95,45, 0,255,0,255);430 });431 it("2d.path.bezierCurveTo.ensuresubpath.2", function () {432 // If there is no subpath, the first control point is added433 const canvas = createCanvas(100, 50);434 const ctx = canvas.getContext("2d");435 const t = new Test();436 ctx.fillStyle = '#f00';437 ctx.fillRect(0, 0, 100, 50);438 ctx.strokeStyle = '#0f0';439 ctx.lineWidth = 50;440 ctx.beginPath();441 ctx.bezierCurveTo(0, 25, 100, 25, 100, 25);442 ctx.stroke();443 _assertPixel(canvas, 50,25, 0,255,0,255);444 _assertPixel(canvas, 5,45, 0,255,0,255);445 });446 it("2d.path.bezierCurveTo.basic", function () {447 const canvas = createCanvas(100, 50);448 const ctx = canvas.getContext("2d");449 const t = new Test();450 ctx.fillStyle = '#f00';451 ctx.fillRect(0, 0, 100, 50);452 ctx.strokeStyle = '#0f0';453 ctx.lineWidth = 50;454 ctx.beginPath();455 ctx.moveTo(0, 25);456 ctx.bezierCurveTo(100, 25, 100, 25, 100, 25);457 ctx.stroke();458 _assertPixel(canvas, 50,25, 0,255,0,255);459 });460 it("2d.path.bezierCurveTo.shape", function () {461 const canvas = createCanvas(100, 50);462 const ctx = canvas.getContext("2d");463 const t = new Test();464 ctx.fillStyle = '#f00';465 ctx.fillRect(0, 0, 100, 50);466 ctx.strokeStyle = '#0f0';467 ctx.lineWidth = 55;468 ctx.beginPath();469 ctx.moveTo(-2000, 3100);470 ctx.bezierCurveTo(-2000, -1000, 2100, -1000, 2100, 3100);471 ctx.stroke();472 _assertPixel(canvas, 50,25, 0,255,0,255);473 _assertPixel(canvas, 1,1, 0,255,0,255);474 _assertPixel(canvas, 98,1, 0,255,0,255);475 _assertPixel(canvas, 1,48, 0,255,0,255);476 _assertPixel(canvas, 98,48, 0,255,0,255);477 });478 it("2d.path.bezierCurveTo.scaled", function () {479 const canvas = createCanvas(100, 50);480 const ctx = canvas.getContext("2d");481 const t = new Test();482 ctx.fillStyle = '#f00';483 ctx.fillRect(0, 0, 100, 50);484 ctx.scale(1000, 1000);485 ctx.strokeStyle = '#0f0';486 ctx.lineWidth = 0.055;487 ctx.beginPath();488 ctx.moveTo(-2, 3.1);489 ctx.bezierCurveTo(-2, -1, 2.1, -1, 2.1, 3.1);490 ctx.stroke();491 _assertPixel(canvas, 50,25, 0,255,0,255);492 _assertPixel(canvas, 1,1, 0,255,0,255);493 _assertPixel(canvas, 98,1, 0,255,0,255);494 _assertPixel(canvas, 1,48, 0,255,0,255);495 _assertPixel(canvas, 98,48, 0,255,0,255);496 });497 it("2d.path.bezierCurveTo.nonfinite", function () {498 // bezierCurveTo() with Infinity/NaN is ignored499 const canvas = createCanvas(100, 50);500 const ctx = canvas.getContext("2d");501 const t = new Test();502 ctx.moveTo(0, 0);503 ctx.lineTo(100, 0);504 ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, 50);505 ctx.bezierCurveTo(-Infinity, 50, 0, 50, 0, 50);506 ctx.bezierCurveTo(NaN, 50, 0, 50, 0, 50);507 ctx.bezierCurveTo(0, Infinity, 0, 50, 0, 50);508 ctx.bezierCurveTo(0, -Infinity, 0, 50, 0, 50);509 ctx.bezierCurveTo(0, NaN, 0, 50, 0, 50);510 ctx.bezierCurveTo(0, 50, Infinity, 50, 0, 50);511 ctx.bezierCurveTo(0, 50, -Infinity, 50, 0, 50);512 ctx.bezierCurveTo(0, 50, NaN, 50, 0, 50);513 ctx.bezierCurveTo(0, 50, 0, Infinity, 0, 50);514 ctx.bezierCurveTo(0, 50, 0, -Infinity, 0, 50);515 ctx.bezierCurveTo(0, 50, 0, NaN, 0, 50);516 ctx.bezierCurveTo(0, 50, 0, 50, Infinity, 50);517 ctx.bezierCurveTo(0, 50, 0, 50, -Infinity, 50);518 ctx.bezierCurveTo(0, 50, 0, 50, NaN, 50);519 ctx.bezierCurveTo(0, 50, 0, 50, 0, Infinity);520 ctx.bezierCurveTo(0, 50, 0, 50, 0, -Infinity);521 ctx.bezierCurveTo(0, 50, 0, 50, 0, NaN);522 ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, 50);523 ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, 50);524 ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, 50);525 ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, 50);526 ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);527 ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, Infinity);528 ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, 50);529 ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, Infinity);530 ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, Infinity);531 ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, 50);532 ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, 50);533 ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, Infinity);534 ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, Infinity);535 ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, 50);536 ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, Infinity);537 ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, Infinity);538 ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, 50);539 ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, 50);540 ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, 50);541 ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, Infinity);542 ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, Infinity);543 ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, 50);544 ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, Infinity);545 ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, Infinity);546 ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, 50);547 ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, 50);548 ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, Infinity);549 ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, Infinity);550 ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, 50);551 ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, Infinity);552 ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, Infinity);553 ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, 50);554 ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, 50);555 ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, 50);556 ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, Infinity);557 ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, Infinity);558 ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, 50);559 ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, Infinity);560 ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, Infinity);561 ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, 50);562 ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, 50);563 ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, Infinity);564 ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, Infinity);565 ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, 50);566 ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, Infinity);567 ctx.bezierCurveTo(0, Infinity, 0, 50, 0, Infinity);568 ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, 50);569 ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, 50);570 ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, Infinity);571 ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, Infinity);572 ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, 50);573 ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, Infinity);574 ctx.bezierCurveTo(0, 50, Infinity, 50, 0, Infinity);575 ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, 50);576 ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, Infinity);577 ctx.bezierCurveTo(0, 50, 0, Infinity, 0, Infinity);578 ctx.bezierCurveTo(0, 50, 0, 50, Infinity, Infinity);579 ctx.lineTo(100, 50);580 ctx.lineTo(0, 50);581 ctx.fillStyle = '#0f0';582 ctx.fill();583 _assertPixel(canvas, 50,25, 0,255,0,255);584 _assertPixel(canvas, 90,45, 0,255,0,255);585 });586 it("2d.path.arcTo.ensuresubpath.1", function () {587 // If there is no subpath, the first control point is added (and nothing is drawn up to it)588 const canvas = createCanvas(100, 50);589 const ctx = canvas.getContext("2d");590 const t = new Test();591 ctx.fillStyle = '#0f0';592 ctx.fillRect(0, 0, 100, 50);593 ctx.lineWidth = 50;594 ctx.strokeStyle = '#f00';595 ctx.beginPath();596 ctx.arcTo(100, 50, 200, 50, 0.1);597 ctx.stroke();598 _assertPixel(canvas, 50,25, 0,255,0,255);599 });600 it("2d.path.arcTo.ensuresubpath.2", function () {601 // If there is no subpath, the first control point is added602 const canvas = createCanvas(100, 50);603 const ctx = canvas.getContext("2d");604 const t = new Test();605 ctx.fillStyle = '#f00';606 ctx.fillRect(0, 0, 100, 50);607 ctx.lineWidth = 50;608 ctx.strokeStyle = '#0f0';609 ctx.beginPath();610 ctx.arcTo(0, 25, 50, 250, 0.1); // adds (x1,y1), draws nothing611 ctx.lineTo(100, 25);612 ctx.stroke();613 _assertPixel(canvas, 50,25, 0,255,0,255);614 });615 it("2d.path.arcTo.coincide.1", function () {616 // arcTo() has no effect if P0 = P1617 const canvas = createCanvas(100, 50);618 const ctx = canvas.getContext("2d");619 const t = new Test();620 ctx.fillStyle = '#f00';621 ctx.fillRect(0, 0, 100, 50);622 ctx.lineWidth = 50;623 624 ctx.strokeStyle = '#0f0';625 ctx.beginPath();626 ctx.moveTo(0, 25);627 ctx.arcTo(0, 25, 50, 1000, 1);628 ctx.lineTo(100, 25);629 ctx.stroke();630 631 ctx.strokeStyle = '#f00';632 ctx.beginPath();633 ctx.moveTo(50, 25);634 ctx.arcTo(50, 25, 100, 25, 1);635 ctx.stroke();636 637 _assertPixel(canvas, 50,1, 0,255,0,255);638 _assertPixel(canvas, 50,25, 0,255,0,255);639 _assertPixel(canvas, 50,48, 0,255,0,255);640 });641 it("2d.path.arcTo.coincide.2", function () {642 // arcTo() draws a straight line to P1 if P1 = P2643 const canvas = createCanvas(100, 50);644 const ctx = canvas.getContext("2d");645 const t = new Test();646 ctx.fillStyle = '#f00';647 ctx.fillRect(0, 0, 100, 50);648 ctx.lineWidth = 50;649 ctx.strokeStyle = '#0f0';650 ctx.beginPath();651 ctx.moveTo(0, 25);652 ctx.arcTo(100, 25, 100, 25, 1);653 ctx.stroke();654 655 _assertPixel(canvas, 50,25, 0,255,0,255);656 });657 it("2d.path.arcTo.collinear.1", function () {658 // arcTo() with all points on a line, and P1 between P0/P2, draws a straight line to P1659 const canvas = createCanvas(100, 50);660 const ctx = canvas.getContext("2d");661 const t = new Test();662 ctx.fillStyle = '#f00';663 ctx.fillRect(0, 0, 100, 50);664 ctx.lineWidth = 50;665 666 ctx.strokeStyle = '#0f0';667 ctx.beginPath();668 ctx.moveTo(0, 25);669 ctx.arcTo(100, 25, 200, 25, 1);670 ctx.stroke();671 672 ctx.strokeStyle = '#f00';673 ctx.beginPath();674 ctx.moveTo(-100, 25);675 ctx.arcTo(0, 25, 100, 25, 1);676 ctx.stroke();677 678 _assertPixel(canvas, 50,25, 0,255,0,255);679 });680 it("2d.path.arcTo.collinear.2", function () {681 // arcTo() with all points on a line, and P2 between P0/P1, draws a straight line to P1682 const canvas = createCanvas(100, 50);683 const ctx = canvas.getContext("2d");684 const t = new Test();685 ctx.fillStyle = '#f00';686 ctx.fillRect(0, 0, 100, 50);687 ctx.lineWidth = 50;688 689 ctx.strokeStyle = '#0f0';690 ctx.beginPath();691 ctx.moveTo(0, 25);692 ctx.arcTo(100, 25, 10, 25, 1);693 ctx.stroke();694 695 ctx.strokeStyle = '#f00';696 ctx.beginPath();697 ctx.moveTo(100, 25);698 ctx.arcTo(200, 25, 110, 25, 1);699 ctx.stroke();700 701 _assertPixel(canvas, 50,25, 0,255,0,255);702 });703 it("2d.path.arcTo.collinear.3", function () {704 // arcTo() with all points on a line, and P0 between P1/P2, draws a straight line to P1705 const canvas = createCanvas(100, 50);706 const ctx = canvas.getContext("2d");707 const t = new Test();708 ctx.fillStyle = '#f00';709 ctx.fillRect(0, 0, 100, 50);710 ctx.lineWidth = 50;711 712 ctx.strokeStyle = '#0f0';713 ctx.beginPath();714 ctx.moveTo(0, 25);715 ctx.arcTo(100, 25, -100, 25, 1);716 ctx.stroke();717 718 ctx.strokeStyle = '#f00';719 ctx.beginPath();720 ctx.moveTo(100, 25);721 ctx.arcTo(200, 25, 0, 25, 1);722 ctx.stroke();723 724 ctx.beginPath();725 ctx.moveTo(-100, 25);726 ctx.arcTo(0, 25, -200, 25, 1);727 ctx.stroke();728 729 _assertPixel(canvas, 50,25, 0,255,0,255);730 });731 it("2d.path.arcTo.shape.curve1", function () {732 // arcTo() curves in the right kind of shape733 const canvas = createCanvas(100, 50);734 const ctx = canvas.getContext("2d");735 const t = new Test();736 var tol = 1.5; // tolerance to avoid antialiasing artifacts737 738 ctx.fillStyle = '#0f0';739 ctx.fillRect(0, 0, 100, 50);740 741 ctx.strokeStyle = '#f00';742 ctx.lineWidth = 10;743 ctx.beginPath();744 ctx.moveTo(10, 25);745 ctx.arcTo(75, 25, 75, 60, 20);746 ctx.stroke();747 748 ctx.fillStyle = '#0f0';749 ctx.beginPath();750 ctx.rect(10, 20, 45, 10);751 ctx.moveTo(80, 45);752 ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true);753 ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false);754 ctx.fill();755 756 _assertPixel(canvas, 50,25, 0,255,0,255);757 _assertPixel(canvas, 55,19, 0,255,0,255);758 _assertPixel(canvas, 55,20, 0,255,0,255);759 _assertPixel(canvas, 55,21, 0,255,0,255);760 _assertPixel(canvas, 64,22, 0,255,0,255);761 _assertPixel(canvas, 65,21, 0,255,0,255);762 _assertPixel(canvas, 72,28, 0,255,0,255);763 _assertPixel(canvas, 73,27, 0,255,0,255);764 _assertPixel(canvas, 78,36, 0,255,0,255);765 _assertPixel(canvas, 79,35, 0,255,0,255);766 _assertPixel(canvas, 80,44, 0,255,0,255);767 _assertPixel(canvas, 80,45, 0,255,0,255);768 _assertPixel(canvas, 80,46, 0,255,0,255);769 _assertPixel(canvas, 65,45, 0,255,0,255);770 });771 it("2d.path.arcTo.shape.curve2", function () {772 // arcTo() curves in the right kind of shape773 const canvas = createCanvas(100, 50);774 const ctx = canvas.getContext("2d");775 const t = new Test();776 var tol = 1.5; // tolerance to avoid antialiasing artifacts777 778 ctx.fillStyle = '#0f0';779 ctx.fillRect(0, 0, 100, 50);780 781 ctx.fillStyle = '#f00';782 ctx.beginPath();783 ctx.rect(10, 20, 45, 10);784 ctx.moveTo(80, 45);785 ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true);786 ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false);787 ctx.fill();788 789 ctx.strokeStyle = '#0f0';790 ctx.lineWidth = 10;791 ctx.beginPath();792 ctx.moveTo(10, 25);793 ctx.arcTo(75, 25, 75, 60, 20);794 ctx.stroke();795 796 _assertPixel(canvas, 50,25, 0,255,0,255);797 _assertPixel(canvas, 55,19, 0,255,0,255);798 _assertPixel(canvas, 55,20, 0,255,0,255);799 _assertPixel(canvas, 55,21, 0,255,0,255);800 _assertPixel(canvas, 64,22, 0,255,0,255);801 _assertPixel(canvas, 65,21, 0,255,0,255);802 _assertPixel(canvas, 72,28, 0,255,0,255);803 _assertPixel(canvas, 73,27, 0,255,0,255);804 _assertPixel(canvas, 78,36, 0,255,0,255);805 _assertPixel(canvas, 79,35, 0,255,0,255);806 _assertPixel(canvas, 80,44, 0,255,0,255);807 _assertPixel(canvas, 80,45, 0,255,0,255);808 _assertPixel(canvas, 80,46, 0,255,0,255);809 });810 it("2d.path.arcTo.shape.start", function () {811 // arcTo() draws a straight line from P0 to P1812 const canvas = createCanvas(100, 50);813 const ctx = canvas.getContext("2d");814 const t = new Test();815 ctx.fillStyle = '#f00';816 ctx.fillRect(0, 0, 100, 50);817 ctx.strokeStyle = '#0f0';818 ctx.lineWidth = 50;819 ctx.beginPath();820 ctx.moveTo(0, 25);821 ctx.arcTo(200, 25, 200, 50, 10);822 ctx.stroke();823 824 _assertPixel(canvas, 1,1, 0,255,0,255);825 _assertPixel(canvas, 1,48, 0,255,0,255);826 _assertPixel(canvas, 50,25, 0,255,0,255);827 _assertPixel(canvas, 98,1, 0,255,0,255);828 _assertPixel(canvas, 98,48, 0,255,0,255);829 });830 it("2d.path.arcTo.shape.end", function () {831 // arcTo() does not draw anything from P1 to P2832 const canvas = createCanvas(100, 50);833 const ctx = canvas.getContext("2d");834 const t = new Test();835 ctx.fillStyle = '#0f0';836 ctx.fillRect(0, 0, 100, 50);837 ctx.strokeStyle = '#f00';838 ctx.lineWidth = 50;839 ctx.beginPath();840 ctx.moveTo(-100, -100);841 ctx.arcTo(-100, 25, 200, 25, 10);842 ctx.stroke();843 844 _assertPixel(canvas, 1,1, 0,255,0,255);845 _assertPixel(canvas, 1,48, 0,255,0,255);846 _assertPixel(canvas, 50,25, 0,255,0,255);847 _assertPixel(canvas, 98,1, 0,255,0,255);848 _assertPixel(canvas, 98,48, 0,255,0,255);849 });850 it("2d.path.arcTo.negative", function () {851 // arcTo() with negative radius throws an exception852 const canvas = createCanvas(100, 50);853 const ctx = canvas.getContext("2d");854 const t = new Test();855 assert.throws(function() { ctx.arcTo(0, 0, 0, 0, -1); }, /INDEX_SIZE_ERR/);856 var path = new Path2D();857 assert.throws(function() { path.arcTo(10, 10, 20, 20, -5); }, /INDEX_SIZE_ERR/);858 });859 it("2d.path.arcTo.zero.1", function () {860 // arcTo() with zero radius draws a straight line from P0 to P1861 const canvas = createCanvas(100, 50);862 const ctx = canvas.getContext("2d");863 const t = new Test();864 ctx.fillStyle = '#f00';865 ctx.fillRect(0, 0, 100, 50);866 ctx.lineWidth = 50;867 868 ctx.strokeStyle = '#0f0';869 ctx.beginPath();870 ctx.moveTo(0, 25);871 ctx.arcTo(100, 25, 100, 100, 0);872 ctx.stroke();873 874 ctx.strokeStyle = '#f00';875 ctx.beginPath();876 ctx.moveTo(0, -25);877 ctx.arcTo(50, -25, 50, 50, 0);878 ctx.stroke();879 880 _assertPixel(canvas, 50,25, 0,255,0,255);881 });882 it("2d.path.arcTo.zero.2", function () {883 // arcTo() with zero radius draws a straight line from P0 to P1, even when all points are collinear884 const canvas = createCanvas(100, 50);885 const ctx = canvas.getContext("2d");886 const t = new Test();887 ctx.fillStyle = '#f00';888 ctx.fillRect(0, 0, 100, 50);889 ctx.lineWidth = 50;890 891 ctx.strokeStyle = '#0f0';892 ctx.beginPath();893 ctx.moveTo(0, 25);894 ctx.arcTo(100, 25, -100, 25, 0);895 ctx.stroke();896 897 ctx.strokeStyle = '#f00';898 ctx.beginPath();899 ctx.moveTo(100, 25);900 ctx.arcTo(200, 25, 50, 25, 0);901 ctx.stroke();902 903 _assertPixel(canvas, 50,25, 0,255,0,255);904 });905 it("2d.path.arcTo.transformation", function () {906 // arcTo joins up to the last subpath point correctly907 const canvas = createCanvas(100, 50);908 const ctx = canvas.getContext("2d");909 const t = new Test();910 ctx.fillStyle = '#f00';911 ctx.fillRect(0, 0, 100, 50);912 913 ctx.fillStyle = '#0f0';914 ctx.beginPath();915 ctx.moveTo(0, 50);916 ctx.translate(100, 0);917 ctx.arcTo(50, 50, 50, 0, 50);918 ctx.lineTo(-100, 0);919 ctx.fill();920 921 _assertPixel(canvas, 0,0, 0,255,0,255);922 _assertPixel(canvas, 50,0, 0,255,0,255);923 _assertPixel(canvas, 99,0, 0,255,0,255);924 _assertPixel(canvas, 0,25, 0,255,0,255);925 _assertPixel(canvas, 50,25, 0,255,0,255);926 _assertPixel(canvas, 99,25, 0,255,0,255);927 _assertPixel(canvas, 0,49, 0,255,0,255);928 _assertPixel(canvas, 50,49, 0,255,0,255);929 _assertPixel(canvas, 99,49, 0,255,0,255);930 });931 it("2d.path.arcTo.scale", function () {932 // arcTo scales the curve, not just the control points933 const canvas = createCanvas(100, 50);934 const ctx = canvas.getContext("2d");935 const t = new Test();936 ctx.fillStyle = '#f00';937 ctx.fillRect(0, 0, 100, 50);938 939 ctx.fillStyle = '#0f0';940 ctx.beginPath();941 ctx.moveTo(0, 50);942 ctx.translate(100, 0);943 ctx.scale(0.1, 1);944 ctx.arcTo(50, 50, 50, 0, 50);945 ctx.lineTo(-1000, 0);946 ctx.fill();947 948 _assertPixel(canvas, 0,0, 0,255,0,255);949 _assertPixel(canvas, 50,0, 0,255,0,255);950 _assertPixel(canvas, 99,0, 0,255,0,255);951 _assertPixel(canvas, 0,25, 0,255,0,255);952 _assertPixel(canvas, 50,25, 0,255,0,255);953 _assertPixel(canvas, 99,25, 0,255,0,255);954 _assertPixel(canvas, 0,49, 0,255,0,255);955 _assertPixel(canvas, 50,49, 0,255,0,255);956 _assertPixel(canvas, 99,49, 0,255,0,255);957 });958 it("2d.path.arcTo.nonfinite", function () {959 // arcTo() with Infinity/NaN is ignored960 const canvas = createCanvas(100, 50);961 const ctx = canvas.getContext("2d");962 const t = new Test();963 ctx.moveTo(0, 0);964 ctx.lineTo(100, 0);965 ctx.arcTo(Infinity, 50, 0, 50, 0);966 ctx.arcTo(-Infinity, 50, 0, 50, 0);967 ctx.arcTo(NaN, 50, 0, 50, 0);968 ctx.arcTo(0, Infinity, 0, 50, 0);969 ctx.arcTo(0, -Infinity, 0, 50, 0);970 ctx.arcTo(0, NaN, 0, 50, 0);971 ctx.arcTo(0, 50, Infinity, 50, 0);972 ctx.arcTo(0, 50, -Infinity, 50, 0);973 ctx.arcTo(0, 50, NaN, 50, 0);974 ctx.arcTo(0, 50, 0, Infinity, 0);975 ctx.arcTo(0, 50, 0, -Infinity, 0);976 ctx.arcTo(0, 50, 0, NaN, 0);977 ctx.arcTo(0, 50, 0, 50, Infinity);978 ctx.arcTo(0, 50, 0, 50, -Infinity);979 ctx.arcTo(0, 50, 0, 50, NaN);980 ctx.arcTo(Infinity, Infinity, 0, 50, 0);981 ctx.arcTo(Infinity, Infinity, Infinity, 50, 0);982 ctx.arcTo(Infinity, Infinity, Infinity, Infinity, 0);983 ctx.arcTo(Infinity, Infinity, Infinity, Infinity, Infinity);984 ctx.arcTo(Infinity, Infinity, Infinity, 50, Infinity);985 ctx.arcTo(Infinity, Infinity, 0, Infinity, 0);986 ctx.arcTo(Infinity, Infinity, 0, Infinity, Infinity);987 ctx.arcTo(Infinity, Infinity, 0, 50, Infinity);988 ctx.arcTo(Infinity, 50, Infinity, 50, 0);989 ctx.arcTo(Infinity, 50, Infinity, Infinity, 0);990 ctx.arcTo(Infinity, 50, Infinity, Infinity, Infinity);991 ctx.arcTo(Infinity, 50, Infinity, 50, Infinity);992 ctx.arcTo(Infinity, 50, 0, Infinity, 0);993 ctx.arcTo(Infinity, 50, 0, Infinity, Infinity);994 ctx.arcTo(Infinity, 50, 0, 50, Infinity);995 ctx.arcTo(0, Infinity, Infinity, 50, 0);996 ctx.arcTo(0, Infinity, Infinity, Infinity, 0);997 ctx.arcTo(0, Infinity, Infinity, Infinity, Infinity);998 ctx.arcTo(0, Infinity, Infinity, 50, Infinity);999 ctx.arcTo(0, Infinity, 0, Infinity, 0);1000 ctx.arcTo(0, Infinity, 0, Infinity, Infinity);1001 ctx.arcTo(0, Infinity, 0, 50, Infinity);1002 ctx.arcTo(0, 50, Infinity, Infinity, 0);1003 ctx.arcTo(0, 50, Infinity, Infinity, Infinity);1004 ctx.arcTo(0, 50, Infinity, 50, Infinity);1005 ctx.arcTo(0, 50, 0, Infinity, Infinity);1006 ctx.lineTo(100, 50);1007 ctx.lineTo(0, 50);1008 ctx.fillStyle = '#0f0';1009 ctx.fill();1010 _assertPixel(canvas, 50,25, 0,255,0,255);1011 _assertPixel(canvas, 90,45, 0,255,0,255);1012 });1013 it("2d.path.arc.empty", function () {1014 // arc() with an empty path does not draw a straight line to the start point1015 const canvas = createCanvas(100, 50);1016 const ctx = canvas.getContext("2d");1017 const t = new Test();1018 ctx.fillStyle = '#0f0';1019 ctx.fillRect(0, 0, 100, 50);1020 ctx.lineWidth = 50;1021 ctx.strokeStyle = '#f00';1022 ctx.beginPath();1023 ctx.arc(200, 25, 5, 0, 2*Math.PI, true);1024 ctx.stroke();1025 _assertPixel(canvas, 50,25, 0,255,0,255);1026 });1027 it("2d.path.arc.nonempty", function () {1028 // arc() with a non-empty path does draw a straight line to the start point1029 const canvas = createCanvas(100, 50);1030 const ctx = canvas.getContext("2d");1031 const t = new Test();1032 ctx.fillStyle = '#f00';1033 ctx.fillRect(0, 0, 100, 50);1034 ctx.lineWidth = 50;1035 ctx.strokeStyle = '#0f0';1036 ctx.beginPath();1037 ctx.moveTo(0, 25);1038 ctx.arc(200, 25, 5, 0, 2*Math.PI, true);1039 ctx.stroke();1040 _assertPixel(canvas, 50,25, 0,255,0,255);1041 });1042 it("2d.path.arc.end", function () {1043 // arc() adds the end point of the arc to the subpath1044 const canvas = createCanvas(100, 50);1045 const ctx = canvas.getContext("2d");1046 const t = new Test();1047 ctx.fillStyle = '#f00';1048 ctx.fillRect(0, 0, 100, 50);1049 ctx.lineWidth = 50;1050 ctx.strokeStyle = '#0f0';1051 ctx.beginPath();1052 ctx.moveTo(-100, 0);1053 ctx.arc(-100, 0, 25, -Math.PI/2, Math.PI/2, true);1054 ctx.lineTo(100, 25);1055 ctx.stroke();1056 _assertPixel(canvas, 50,25, 0,255,0,255);1057 });1058 it("2d.path.arc.default", function () {1059 // arc() with missing last argument defaults to clockwise1060 const canvas = createCanvas(100, 50);1061 const ctx = canvas.getContext("2d");1062 const t = new Test();1063 ctx.fillStyle = '#0f0';1064 ctx.fillRect(0, 0, 100, 50);1065 ctx.fillStyle = '#f00';1066 ctx.beginPath();1067 ctx.moveTo(100, 0);1068 ctx.arc(100, 0, 150, -Math.PI, Math.PI/2);1069 ctx.fill();1070 _assertPixel(canvas, 50,25, 0,255,0,255);1071 });1072 it("2d.path.arc.angle.1", function () {1073 // arc() draws pi/2 .. -pi anticlockwise correctly1074 const canvas = createCanvas(100, 50);1075 const ctx = canvas.getContext("2d");1076 const t = new Test();1077 ctx.fillStyle = '#0f0';1078 ctx.fillRect(0, 0, 100, 50);1079 ctx.fillStyle = '#f00';1080 ctx.beginPath();1081 ctx.moveTo(100, 0);1082 ctx.arc(100, 0, 150, Math.PI/2, -Math.PI, true);1083 ctx.fill();1084 _assertPixel(canvas, 50,25, 0,255,0,255);1085 });1086 it("2d.path.arc.angle.2", function () {1087 // arc() draws -3pi/2 .. -pi anticlockwise correctly1088 const canvas = createCanvas(100, 50);1089 const ctx = canvas.getContext("2d");1090 const t = new Test();1091 ctx.fillStyle = '#0f0';1092 ctx.fillRect(0, 0, 100, 50);1093 ctx.fillStyle = '#f00';1094 ctx.beginPath();1095 ctx.moveTo(100, 0);1096 ctx.arc(100, 0, 150, -3*Math.PI/2, -Math.PI, true);1097 ctx.fill();1098 _assertPixel(canvas, 50,25, 0,255,0,255);1099 });1100 it("2d.path.arc.angle.3", function () {1101 // arc() wraps angles mod 2pi when anticlockwise and end > start+2pi1102 const canvas = createCanvas(100, 50);1103 const ctx = canvas.getContext("2d");1104 const t = new Test();1105 ctx.fillStyle = '#0f0';1106 ctx.fillRect(0, 0, 100, 50);1107 ctx.fillStyle = '#f00';1108 ctx.beginPath();1109 ctx.moveTo(100, 0);1110 ctx.arc(100, 0, 150, (512+1/2)*Math.PI, (1024-1)*Math.PI, true);1111 ctx.fill();1112 _assertPixel(canvas, 50,25, 0,255,0,255);1113 });1114 it("2d.path.arc.angle.4", function () {1115 // arc() draws a full circle when clockwise and end > start+2pi1116 const canvas = createCanvas(100, 50);1117 const ctx = canvas.getContext("2d");1118 const t = new Test();1119 ctx.fillStyle = '#f00';1120 ctx.fillRect(0, 0, 100, 50);1121 ctx.fillStyle = '#0f0';1122 ctx.beginPath();1123 ctx.moveTo(50, 25);1124 ctx.arc(50, 25, 60, (512+1/2)*Math.PI, (1024-1)*Math.PI, false);1125 ctx.fill();1126 _assertPixel(canvas, 1,1, 0,255,0,255);1127 _assertPixel(canvas, 98,1, 0,255,0,255);1128 _assertPixel(canvas, 1,48, 0,255,0,255);1129 _assertPixel(canvas, 98,48, 0,255,0,255);1130 });1131 it("2d.path.arc.angle.5", function () {1132 // arc() wraps angles mod 2pi when clockwise and start > end+2pi1133 const canvas = createCanvas(100, 50);1134 const ctx = canvas.getContext("2d");1135 const t = new Test();1136 ctx.fillStyle = '#0f0';1137 ctx.fillRect(0, 0, 100, 50);1138 ctx.fillStyle = '#f00';1139 ctx.beginPath();1140 ctx.moveTo(100, 0);1141 ctx.arc(100, 0, 150, (1024-1)*Math.PI, (512+1/2)*Math.PI, false);1142 ctx.fill();1143 _assertPixel(canvas, 50,25, 0,255,0,255);1144 });1145 it("2d.path.arc.angle.6", function () {1146 // arc() draws a full circle when anticlockwise and start > end+2pi1147 const canvas = createCanvas(100, 50);1148 const ctx = canvas.getContext("2d");1149 const t = new Test();1150 ctx.fillStyle = '#f00';1151 ctx.fillRect(0, 0, 100, 50);1152 ctx.fillStyle = '#0f0';1153 ctx.beginPath();1154 ctx.moveTo(50, 25);1155 ctx.arc(50, 25, 60, (1024-1)*Math.PI, (512+1/2)*Math.PI, true);1156 ctx.fill();1157 _assertPixel(canvas, 1,1, 0,255,0,255);1158 _assertPixel(canvas, 98,1, 0,255,0,255);1159 _assertPixel(canvas, 1,48, 0,255,0,255);1160 _assertPixel(canvas, 98,48, 0,255,0,255);1161 });1162 it("2d.path.arc.zero.1", function () {1163 // arc() draws nothing when startAngle = endAngle and anticlockwise1164 const canvas = createCanvas(100, 50);1165 const ctx = canvas.getContext("2d");1166 const t = new Test();1167 ctx.fillStyle = '#0f0';1168 ctx.fillRect(0, 0, 100, 50);1169 ctx.strokeStyle = '#f00';1170 ctx.lineWidth = 100;1171 ctx.beginPath();1172 ctx.arc(50, 25, 50, 0, 0, true);1173 ctx.stroke();1174 _assertPixel(canvas, 50,20, 0,255,0,255);1175 });1176 it("2d.path.arc.zero.2", function () {1177 // arc() draws nothing when startAngle = endAngle and clockwise1178 const canvas = createCanvas(100, 50);1179 const ctx = canvas.getContext("2d");1180 const t = new Test();1181 ctx.fillStyle = '#0f0';1182 ctx.fillRect(0, 0, 100, 50);1183 ctx.strokeStyle = '#f00';1184 ctx.lineWidth = 100;1185 ctx.beginPath();1186 ctx.arc(50, 25, 50, 0, 0, false);1187 ctx.stroke();1188 _assertPixel(canvas, 50,20, 0,255,0,255);1189 });1190 it("2d.path.arc.twopie.1", function () {1191 // arc() draws nothing when end = start + 2pi-e and anticlockwise1192 const canvas = createCanvas(100, 50);1193 const ctx = canvas.getContext("2d");1194 const t = new Test();1195 ctx.fillStyle = '#0f0';1196 ctx.fillRect(0, 0, 100, 50);1197 ctx.strokeStyle = '#f00';1198 ctx.lineWidth = 100;1199 ctx.beginPath();1200 ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, true);1201 ctx.stroke();1202 _assertPixel(canvas, 50,20, 0,255,0,255);1203 });1204 it("2d.path.arc.twopie.2", function () {1205 // arc() draws a full circle when end = start + 2pi-e and clockwise1206 const canvas = createCanvas(100, 50);1207 const ctx = canvas.getContext("2d");1208 const t = new Test();1209 ctx.fillStyle = '#f00';1210 ctx.fillRect(0, 0, 100, 50);1211 ctx.strokeStyle = '#0f0';1212 ctx.lineWidth = 100;1213 ctx.beginPath();1214 ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, false);1215 ctx.stroke();1216 _assertPixel(canvas, 50,20, 0,255,0,255);1217 });1218 it("2d.path.arc.twopie.3", function () {1219 // arc() draws a full circle when end = start + 2pi+e and anticlockwise1220 const canvas = createCanvas(100, 50);1221 const ctx = canvas.getContext("2d");1222 const t = new Test();1223 ctx.fillStyle = '#f00';1224 ctx.fillRect(0, 0, 100, 50);1225 ctx.strokeStyle = '#0f0';1226 ctx.lineWidth = 100;1227 ctx.beginPath();1228 ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, true);1229 ctx.stroke();1230 _assertPixel(canvas, 50,20, 0,255,0,255);1231 });1232 it("2d.path.arc.twopie.4", function () {1233 // arc() draws nothing when end = start + 2pi+e and clockwise1234 const canvas = createCanvas(100, 50);1235 const ctx = canvas.getContext("2d");1236 const t = new Test();1237 ctx.fillStyle = '#f00';1238 ctx.fillRect(0, 0, 100, 50);1239 ctx.strokeStyle = '#0f0';1240 ctx.lineWidth = 100;1241 ctx.beginPath();1242 ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, false);1243 ctx.stroke();1244 _assertPixel(canvas, 50,20, 0,255,0,255);1245 });1246 it("2d.path.arc.shape.1", function () {1247 // arc() from 0 to pi does not draw anything in the wrong half1248 const canvas = createCanvas(100, 50);1249 const ctx = canvas.getContext("2d");1250 const t = new Test();1251 ctx.fillStyle = '#0f0';1252 ctx.fillRect(0, 0, 100, 50);1253 ctx.lineWidth = 50;1254 ctx.strokeStyle = '#f00';1255 ctx.beginPath();1256 ctx.arc(50, 50, 50, 0, Math.PI, false);1257 ctx.stroke();1258 _assertPixel(canvas, 50,25, 0,255,0,255);1259 _assertPixel(canvas, 1,1, 0,255,0,255);1260 _assertPixel(canvas, 98,1, 0,255,0,255);1261 _assertPixel(canvas, 1,48, 0,255,0,255);1262 _assertPixel(canvas, 20,48, 0,255,0,255);1263 _assertPixel(canvas, 98,48, 0,255,0,255);1264 });1265 it("2d.path.arc.shape.2", function () {1266 // arc() from 0 to pi draws stuff in the right half1267 const canvas = createCanvas(100, 50);1268 const ctx = canvas.getContext("2d");1269 const t = new Test();1270 ctx.fillStyle = '#f00';1271 ctx.fillRect(0, 0, 100, 50);1272 ctx.lineWidth = 100;1273 ctx.strokeStyle = '#0f0';1274 ctx.beginPath();1275 ctx.arc(50, 50, 50, 0, Math.PI, true);1276 ctx.stroke();1277 _assertPixel(canvas, 50,25, 0,255,0,255);1278 _assertPixel(canvas, 1,1, 0,255,0,255);1279 _assertPixel(canvas, 98,1, 0,255,0,255);1280 _assertPixel(canvas, 1,48, 0,255,0,255);1281 _assertPixel(canvas, 20,48, 0,255,0,255);1282 _assertPixel(canvas, 98,48, 0,255,0,255);1283 });1284 it("2d.path.arc.shape.3", function () {1285 // arc() from 0 to -pi/2 does not draw anything in the wrong quadrant1286 const canvas = createCanvas(100, 50);1287 const ctx = canvas.getContext("2d");1288 const t = new Test();1289 ctx.fillStyle = '#0f0';1290 ctx.fillRect(0, 0, 100, 50);1291 ctx.lineWidth = 100;1292 ctx.strokeStyle = '#f00';1293 ctx.beginPath();1294 ctx.arc(0, 50, 50, 0, -Math.PI/2, false);1295 ctx.stroke();1296 _assertPixel(canvas, 50,25, 0,255,0,255);1297 _assertPixel(canvas, 1,1, 0,255,0,255);1298 _assertPixel(canvas, 98,1, 0,255,0,255);1299 _assertPixel(canvas, 1,48, 0,255,0,255);1300 _assertPixel(canvas, 98,48, 0,255,0,255);1301 });1302 it("2d.path.arc.shape.4", function () {1303 // arc() from 0 to -pi/2 draws stuff in the right quadrant1304 const canvas = createCanvas(100, 50);1305 const ctx = canvas.getContext("2d");1306 const t = new Test();1307 ctx.fillStyle = '#f00';1308 ctx.fillRect(0, 0, 100, 50);1309 ctx.lineWidth = 150;1310 ctx.strokeStyle = '#0f0';1311 ctx.beginPath();1312 ctx.arc(-50, 50, 100, 0, -Math.PI/2, true);1313 ctx.stroke();1314 _assertPixel(canvas, 50,25, 0,255,0,255);1315 _assertPixel(canvas, 1,1, 0,255,0,255);1316 _assertPixel(canvas, 98,1, 0,255,0,255);1317 _assertPixel(canvas, 1,48, 0,255,0,255);1318 _assertPixel(canvas, 98,48, 0,255,0,255);1319 });1320 it("2d.path.arc.shape.5", function () {1321 // arc() from 0 to 5pi does not draw crazy things1322 const canvas = createCanvas(100, 50);1323 const ctx = canvas.getContext("2d");1324 const t = new Test();1325 ctx.fillStyle = '#0f0';1326 ctx.fillRect(0, 0, 100, 50);1327 ctx.lineWidth = 200;1328 ctx.strokeStyle = '#f00';1329 ctx.beginPath();1330 ctx.arc(300, 0, 100, 0, 5*Math.PI, false);1331 ctx.stroke();1332 _assertPixel(canvas, 50,25, 0,255,0,255);1333 _assertPixel(canvas, 1,1, 0,255,0,255);1334 _assertPixel(canvas, 98,1, 0,255,0,255);1335 _assertPixel(canvas, 1,48, 0,255,0,255);1336 _assertPixel(canvas, 98,48, 0,255,0,255);1337 });1338 it("2d.path.arc.selfintersect.1", function () {1339 // arc() with lineWidth > 2*radius is drawn sensibly1340 const canvas = createCanvas(100, 50);1341 const ctx = canvas.getContext("2d");1342 const t = new Test();1343 ctx.fillStyle = '#0f0';1344 ctx.fillRect(0, 0, 100, 50);1345 ctx.lineWidth = 200;1346 ctx.strokeStyle = '#f00';1347 ctx.beginPath();1348 ctx.arc(100, 50, 25, 0, -Math.PI/2, true);1349 ctx.stroke();1350 ctx.beginPath();1351 ctx.arc(0, 0, 25, 0, -Math.PI/2, true);1352 ctx.stroke();1353 _assertPixel(canvas, 1,1, 0,255,0,255);1354 _assertPixel(canvas, 50,25, 0,255,0,255);1355 });1356 it("2d.path.arc.selfintersect.2", function () {1357 // arc() with lineWidth > 2*radius is drawn sensibly1358 const canvas = createCanvas(100, 50);1359 const ctx = canvas.getContext("2d");1360 const t = new Test();1361 ctx.fillStyle = '#f00';1362 ctx.fillRect(0, 0, 100, 50);1363 ctx.lineWidth = 180;1364 ctx.strokeStyle = '#0f0';1365 ctx.beginPath();1366 ctx.arc(-50, 50, 25, 0, -Math.PI/2, true);1367 ctx.stroke();1368 ctx.beginPath();1369 ctx.arc(100, 0, 25, 0, -Math.PI/2, true);1370 ctx.stroke();1371 _assertPixel(canvas, 50,25, 0,255,0,255);1372 _assertPixel(canvas, 90,10, 0,255,0,255);1373 _assertPixel(canvas, 97,1, 0,255,0,255);1374 _assertPixel(canvas, 97,2, 0,255,0,255);1375 _assertPixel(canvas, 97,3, 0,255,0,255);1376 _assertPixel(canvas, 2,48, 0,255,0,255);1377 });1378 it("2d.path.arc.negative", function () {1379 // arc() with negative radius throws INDEX_SIZE_ERR1380 const canvas = createCanvas(100, 50);1381 const ctx = canvas.getContext("2d");1382 const t = new Test();1383 assert.throws(function() { ctx.arc(0, 0, -1, 0, 0, true); }, /INDEX_SIZE_ERR/);1384 var path = new Path2D();1385 assert.throws(function() { path.arc(10, 10, -5, 0, 1, false); }, /INDEX_SIZE_ERR/);1386 });1387 it("2d.path.arc.zeroradius", function () {1388 // arc() with zero radius draws a line to the start point1389 const canvas = createCanvas(100, 50);1390 const ctx = canvas.getContext("2d");1391 const t = new Test();1392 ctx.fillStyle = '#f00'1393 ctx.fillRect(0, 0, 100, 50);1394 ctx.lineWidth = 50;1395 ctx.strokeStyle = '#0f0';1396 ctx.beginPath();1397 ctx.moveTo(0, 25);1398 ctx.arc(200, 25, 0, 0, Math.PI, true);1399 ctx.stroke();1400 _assertPixel(canvas, 50,25, 0,255,0,255);1401 });1402 it("2d.path.arc.scale.1", function () {1403 // Non-uniformly scaled arcs are the right shape1404 const canvas = createCanvas(100, 50);1405 const ctx = canvas.getContext("2d");1406 const t = new Test();1407 ctx.fillStyle = '#f00';1408 ctx.fillRect(0, 0, 100, 50);1409 ctx.scale(2, 0.5);1410 ctx.fillStyle = '#0f0';1411 ctx.beginPath();1412 ctx.arc(25, 50, 56, 0, 2*Math.PI, false);1413 ctx.fill();1414 ctx.fillStyle = '#f00';1415 ctx.beginPath();1416 ctx.moveTo(-25, 50);1417 ctx.arc(-25, 50, 24, 0, 2*Math.PI, false);1418 ctx.moveTo(75, 50);1419 ctx.arc(75, 50, 24, 0, 2*Math.PI, false);1420 ctx.moveTo(25, -25);1421 ctx.arc(25, -25, 24, 0, 2*Math.PI, false);1422 ctx.moveTo(25, 125);1423 ctx.arc(25, 125, 24, 0, 2*Math.PI, false);1424 ctx.fill();1425 1426 _assertPixel(canvas, 0,0, 0,255,0,255);1427 _assertPixel(canvas, 50,0, 0,255,0,255);1428 _assertPixel(canvas, 99,0, 0,255,0,255);1429 _assertPixel(canvas, 0,25, 0,255,0,255);1430 _assertPixel(canvas, 50,25, 0,255,0,255);1431 _assertPixel(canvas, 99,25, 0,255,0,255);1432 _assertPixel(canvas, 0,49, 0,255,0,255);1433 _assertPixel(canvas, 50,49, 0,255,0,255);1434 _assertPixel(canvas, 99,49, 0,255,0,255);1435 });1436 it("2d.path.arc.scale.2", function () {1437 // Highly scaled arcs are the right shape1438 const canvas = createCanvas(100, 50);1439 const ctx = canvas.getContext("2d");1440 const t = new Test();1441 ctx.fillStyle = '#f00';1442 ctx.fillRect(0, 0, 100, 50);1443 ctx.scale(100, 100);1444 ctx.strokeStyle = '#0f0';1445 ctx.lineWidth = 1.2;1446 ctx.beginPath();1447 ctx.arc(0, 0, 0.6, 0, Math.PI/2, false);1448 ctx.stroke();1449 1450 _assertPixel(canvas, 1,1, 0,255,0,255);1451 _assertPixel(canvas, 50,1, 0,255,0,255);1452 _assertPixel(canvas, 98,1, 0,255,0,255);1453 _assertPixel(canvas, 1,25, 0,255,0,255);1454 _assertPixel(canvas, 50,25, 0,255,0,255);1455 _assertPixel(canvas, 98,25, 0,255,0,255);1456 _assertPixel(canvas, 1,48, 0,255,0,255);1457 _assertPixel(canvas, 50,48, 0,255,0,255);1458 _assertPixel(canvas, 98,48, 0,255,0,255);1459 });1460 it("2d.path.arc.nonfinite", function () {1461 // arc() with Infinity/NaN is ignored1462 const canvas = createCanvas(100, 50);1463 const ctx = canvas.getContext("2d");1464 const t = new Test();1465 ctx.fillStyle = '#f00';1466 ctx.fillRect(0, 0, 100, 50);1467 ctx.moveTo(0, 0);1468 ctx.lineTo(100, 0);1469 ctx.arc(Infinity, 0, 50, 0, 2*Math.PI, true);1470 ctx.arc(-Infinity, 0, 50, 0, 2*Math.PI, true);1471 ctx.arc(NaN, 0, 50, 0, 2*Math.PI, true);1472 ctx.arc(0, Infinity, 50, 0, 2*Math.PI, true);1473 ctx.arc(0, -Infinity, 50, 0, 2*Math.PI, true);1474 ctx.arc(0, NaN, 50, 0, 2*Math.PI, true);1475 ctx.arc(0, 0, Infinity, 0, 2*Math.PI, true);1476 ctx.arc(0, 0, -Infinity, 0, 2*Math.PI, true);1477 ctx.arc(0, 0, NaN, 0, 2*Math.PI, true);1478 ctx.arc(0, 0, 50, Infinity, 2*Math.PI, true);1479 ctx.arc(0, 0, 50, -Infinity, 2*Math.PI, true);1480 ctx.arc(0, 0, 50, NaN, 2*Math.PI, true);1481 ctx.arc(0, 0, 50, 0, Infinity, true);1482 ctx.arc(0, 0, 50, 0, -Infinity, true);1483 ctx.arc(0, 0, 50, 0, NaN, true);1484 ctx.arc(Infinity, Infinity, 50, 0, 2*Math.PI, true);1485 ctx.arc(Infinity, Infinity, Infinity, 0, 2*Math.PI, true);1486 ctx.arc(Infinity, Infinity, Infinity, Infinity, 2*Math.PI, true);1487 ctx.arc(Infinity, Infinity, Infinity, Infinity, Infinity, true);1488 ctx.arc(Infinity, Infinity, Infinity, 0, Infinity, true);1489 ctx.arc(Infinity, Infinity, 50, Infinity, 2*Math.PI, true);1490 ctx.arc(Infinity, Infinity, 50, Infinity, Infinity, true);1491 ctx.arc(Infinity, Infinity, 50, 0, Infinity, true);1492 ctx.arc(Infinity, 0, Infinity, 0, 2*Math.PI, true);1493 ctx.arc(Infinity, 0, Infinity, Infinity, 2*Math.PI, true);1494 ctx.arc(Infinity, 0, Infinity, Infinity, Infinity, true);1495 ctx.arc(Infinity, 0, Infinity, 0, Infinity, true);1496 ctx.arc(Infinity, 0, 50, Infinity, 2*Math.PI, true);1497 ctx.arc(Infinity, 0, 50, Infinity, Infinity, true);1498 ctx.arc(Infinity, 0, 50, 0, Infinity, true);1499 ctx.arc(0, Infinity, Infinity, 0, 2*Math.PI, true);1500 ctx.arc(0, Infinity, Infinity, Infinity, 2*Math.PI, true);1501 ctx.arc(0, Infinity, Infinity, Infinity, Infinity, true);1502 ctx.arc(0, Infinity, Infinity, 0, Infinity, true);1503 ctx.arc(0, Infinity, 50, Infinity, 2*Math.PI, true);1504 ctx.arc(0, Infinity, 50, Infinity, Infinity, true);1505 ctx.arc(0, Infinity, 50, 0, Infinity, true);1506 ctx.arc(0, 0, Infinity, Infinity, 2*Math.PI, true);1507 ctx.arc(0, 0, Infinity, Infinity, Infinity, true);1508 ctx.arc(0, 0, Infinity, 0, Infinity, true);1509 ctx.arc(0, 0, 50, Infinity, Infinity, true);1510 ctx.lineTo(100, 50);1511 ctx.lineTo(0, 50);1512 ctx.fillStyle = '#0f0';1513 ctx.fill();1514 _assertPixel(canvas, 50,25, 0,255,0,255);1515 _assertPixel(canvas, 90,45, 0,255,0,255);1516 });1517 it("2d.path.rect.basic", function () {1518 const canvas = createCanvas(100, 50);1519 const ctx = canvas.getContext("2d");1520 const t = new Test();1521 ctx.fillStyle = '#f00';1522 ctx.fillRect(0, 0, 100, 50);1523 ctx.fillStyle = '#0f0';1524 ctx.rect(0, 0, 100, 50);1525 ctx.fill();1526 _assertPixel(canvas, 50,25, 0,255,0,255);1527 });1528 it("2d.path.rect.newsubpath", function () {1529 const canvas = createCanvas(100, 50);1530 const ctx = canvas.getContext("2d");1531 const t = new Test();1532 ctx.fillStyle = '#0f0';1533 ctx.fillRect(0, 0, 100, 50);1534 ctx.beginPath();1535 ctx.strokeStyle = '#f00';1536 ctx.lineWidth = 50;1537 ctx.moveTo(-100, 25);1538 ctx.lineTo(-50, 25);1539 ctx.rect(200, 25, 1, 1);1540 ctx.stroke();1541 _assertPixel(canvas, 50,25, 0,255,0,255);1542 });1543 it("2d.path.rect.closed", function () {1544 const canvas = createCanvas(100, 50);1545 const ctx = canvas.getContext("2d");1546 const t = new Test();1547 ctx.fillStyle = '#f00';1548 ctx.fillRect(0, 0, 100, 50);1549 ctx.strokeStyle = '#0f0';1550 ctx.lineWidth = 200;1551 ctx.lineJoin = 'miter';1552 ctx.rect(100, 50, 100, 100);1553 ctx.stroke();1554 _assertPixel(canvas, 50,25, 0,255,0,255);1555 });1556 it("2d.path.rect.end.1", function () {1557 const canvas = createCanvas(100, 50);1558 const ctx = canvas.getContext("2d");1559 const t = new Test();1560 ctx.fillStyle = '#f00';1561 ctx.fillRect(0, 0, 100, 50);1562 ctx.strokeStyle = '#0f0';1563 ctx.lineWidth = 100;1564 ctx.rect(200, 100, 400, 1000);1565 ctx.lineTo(-2000, -1000);1566 ctx.stroke();1567 _assertPixel(canvas, 50,25, 0,255,0,255);1568 });1569 it("2d.path.rect.end.2", function () {1570 const canvas = createCanvas(100, 50);1571 const ctx = canvas.getContext("2d");1572 const t = new Test();1573 ctx.fillStyle = '#f00';1574 ctx.fillRect(0, 0, 100, 50);1575 ctx.strokeStyle = '#0f0';1576 ctx.lineWidth = 450;1577 ctx.lineCap = 'round';1578 ctx.lineJoin = 'bevel';1579 ctx.rect(150, 150, 2000, 2000);1580 ctx.lineTo(160, 160);1581 ctx.stroke();1582 _assertPixel(canvas, 1,1, 0,255,0,255);1583 _assertPixel(canvas, 98,1, 0,255,0,255);1584 _assertPixel(canvas, 1,48, 0,255,0,255);1585 _assertPixel(canvas, 98,48, 0,255,0,255);1586 });1587 it("2d.path.rect.zero.1", function () {1588 const canvas = createCanvas(100, 50);1589 const ctx = canvas.getContext("2d");1590 const t = new Test();1591 ctx.fillStyle = '#f00';1592 ctx.fillRect(0, 0, 100, 50);1593 ctx.strokeStyle = '#0f0';1594 ctx.lineWidth = 100;1595 ctx.beginPath();1596 ctx.rect(0, 50, 100, 0);1597 ctx.stroke();1598 _assertPixel(canvas, 50,25, 0,255,0,255);1599 });1600 it("2d.path.rect.zero.2", function () {1601 const canvas = createCanvas(100, 50);1602 const ctx = canvas.getContext("2d");1603 const t = new Test();1604 ctx.fillStyle = '#f00';1605 ctx.fillRect(0, 0, 100, 50);1606 ctx.strokeStyle = '#0f0';1607 ctx.lineWidth = 100;1608 ctx.beginPath();1609 ctx.rect(50, -100, 0, 250);1610 ctx.stroke();1611 _assertPixel(canvas, 50,25, 0,255,0,255);1612 });1613 it("2d.path.rect.zero.3", function () {1614 const canvas = createCanvas(100, 50);1615 const ctx = canvas.getContext("2d");1616 const t = new Test();1617 ctx.fillStyle = '#0f0';1618 ctx.fillRect(0, 0, 100, 50);1619 ctx.strokeStyle = '#f00';1620 ctx.lineWidth = 100;1621 ctx.beginPath();1622 ctx.rect(50, 25, 0, 0);1623 ctx.stroke();1624 _assertPixel(canvas, 50,25, 0,255,0,255);1625 });1626 it("2d.path.rect.zero.4", function () {1627 const canvas = createCanvas(100, 50);1628 const ctx = canvas.getContext("2d");1629 const t = new Test();1630 ctx.fillStyle = '#f00';1631 ctx.fillRect(0, 0, 100, 50);1632 ctx.strokeStyle = '#0f0';1633 ctx.lineWidth = 50;1634 ctx.rect(100, 25, 0, 0);1635 ctx.lineTo(0, 25);1636 ctx.stroke();1637 _assertPixel(canvas, 50,25, 0,255,0,255);1638 });1639 it("2d.path.rect.zero.5", function () {1640 const canvas = createCanvas(100, 50);1641 const ctx = canvas.getContext("2d");1642 const t = new Test();1643 ctx.fillStyle = '#0f0';1644 ctx.fillRect(0, 0, 100, 50);1645 ctx.strokeStyle = '#f00';1646 ctx.lineWidth = 50;1647 ctx.moveTo(0, 0);1648 ctx.rect(100, 25, 0, 0);1649 ctx.stroke();1650 _assertPixel(canvas, 50,25, 0,255,0,255);1651 });1652 it("2d.path.rect.zero.6", function () {1653 const canvas = createCanvas(100, 50);1654 const ctx = canvas.getContext("2d");1655 const t = new Test();1656 ctx.fillStyle = '#0f0';1657 ctx.fillRect(0, 0, 100, 50);1658 ctx.strokeStyle = '#f00';1659 ctx.lineJoin = 'miter';1660 ctx.miterLimit = 1.5;1661 ctx.lineWidth = 200;1662 ctx.beginPath();1663 ctx.rect(100, 25, 1000, 0);1664 ctx.stroke();1665 _assertPixel(canvas, 50,25, 0,255,0,255);1666 });1667 it("2d.path.rect.negative", function () {1668 const canvas = createCanvas(100, 50);1669 const ctx = canvas.getContext("2d");1670 const t = new Test();1671 ctx.fillStyle = '#f00';1672 ctx.fillRect(0, 0, 100, 50);1673 ctx.beginPath();1674 ctx.fillStyle = '#0f0';1675 ctx.rect(0, 0, 50, 25);1676 ctx.rect(100, 0, -50, 25);1677 ctx.rect(0, 50, 50, -25);1678 ctx.rect(100, 50, -50, -25);1679 ctx.fill();1680 _assertPixel(canvas, 25,12, 0,255,0,255);1681 _assertPixel(canvas, 75,12, 0,255,0,255);1682 _assertPixel(canvas, 25,37, 0,255,0,255);1683 _assertPixel(canvas, 75,37, 0,255,0,255);1684 });1685 it("2d.path.rect.winding", function () {1686 const canvas = createCanvas(100, 50);1687 const ctx = canvas.getContext("2d");1688 const t = new Test();1689 ctx.fillStyle = '#0f0';1690 ctx.fillRect(0, 0, 100, 50);1691 ctx.beginPath();1692 ctx.fillStyle = '#f00';1693 ctx.rect(0, 0, 50, 50);1694 ctx.rect(100, 50, -50, -50);1695 ctx.rect(0, 25, 100, -25);1696 ctx.rect(100, 25, -100, 25);1697 ctx.fill();1698 _assertPixel(canvas, 25,12, 0,255,0,255);1699 _assertPixel(canvas, 75,12, 0,255,0,255);1700 _assertPixel(canvas, 25,37, 0,255,0,255);1701 _assertPixel(canvas, 75,37, 0,255,0,255);1702 });1703 it("2d.path.rect.selfintersect", function () {1704 const canvas = createCanvas(100, 50);1705 const ctx = canvas.getContext("2d");1706 const t = new Test();1707 ctx.fillStyle = '#f00';1708 ctx.fillRect(0, 0, 100, 50);1709 ctx.strokeStyle = '#0f0';1710 ctx.lineWidth = 90;1711 ctx.beginPath();1712 ctx.rect(45, 20, 10, 10);1713 ctx.stroke();1714 _assertPixel(canvas, 50,25, 0,255,0,255);1715 });1716 it("2d.path.rect.nonfinite", function () {1717 // rect() with Infinity/NaN is ignored1718 const canvas = createCanvas(100, 50);1719 const ctx = canvas.getContext("2d");1720 const t = new Test();1721 ctx.moveTo(0, 0);1722 ctx.lineTo(100, 0);1723 ctx.rect(Infinity, 50, 1, 1);1724 ctx.rect(-Infinity, 50, 1, 1);1725 ctx.rect(NaN, 50, 1, 1);1726 ctx.rect(0, Infinity, 1, 1);1727 ctx.rect(0, -Infinity, 1, 1);1728 ctx.rect(0, NaN, 1, 1);1729 ctx.rect(0, 50, Infinity, 1);1730 ctx.rect(0, 50, -Infinity, 1);1731 ctx.rect(0, 50, NaN, 1);1732 ctx.rect(0, 50, 1, Infinity);1733 ctx.rect(0, 50, 1, -Infinity);1734 ctx.rect(0, 50, 1, NaN);1735 ctx.rect(Infinity, Infinity, 1, 1);1736 ctx.rect(Infinity, Infinity, Infinity, 1);1737 ctx.rect(Infinity, Infinity, Infinity, Infinity);1738 ctx.rect(Infinity, Infinity, 1, Infinity);1739 ctx.rect(Infinity, 50, Infinity, 1);1740 ctx.rect(Infinity, 50, Infinity, Infinity);1741 ctx.rect(Infinity, 50, 1, Infinity);1742 ctx.rect(0, Infinity, Infinity, 1);1743 ctx.rect(0, Infinity, Infinity, Infinity);1744 ctx.rect(0, Infinity, 1, Infinity);1745 ctx.rect(0, 50, Infinity, Infinity);1746 ctx.lineTo(100, 50);1747 ctx.lineTo(0, 50);1748 ctx.fillStyle = '#0f0';1749 ctx.fill();1750 _assertPixel(canvas, 50,25, 0,255,0,255);1751 _assertPixel(canvas, 90,45, 0,255,0,255);1752 });1753 it("2d.path.roundrect.newsubpath", function () {1754 const canvas = createCanvas(100, 50);1755 const ctx = canvas.getContext("2d");1756 const t = new Test();1757 ctx.fillStyle = '#0f0';1758 ctx.fillRect(0, 0, 100, 50);1759 ctx.beginPath();1760 ctx.strokeStyle = '#f00';1761 ctx.lineWidth = 50;1762 ctx.moveTo(-100, 25);1763 ctx.lineTo(-50, 25);1764 ctx.roundRect(200, 25, 1, 1, [0]);1765 ctx.stroke();1766 _assertPixel(canvas, 50,25, 0,255,0,255);1767 });1768 it("2d.path.roundrect.closed", function () {1769 const canvas = createCanvas(100, 50);1770 const ctx = canvas.getContext("2d");1771 const t = new Test();1772 ctx.fillStyle = '#f00';1773 ctx.fillRect(0, 0, 100, 50);1774 ctx.strokeStyle = '#0f0';1775 ctx.lineWidth = 200;1776 ctx.lineJoin = 'miter';1777 ctx.roundRect(100, 50, 100, 100, [0]);1778 ctx.stroke();1779 _assertPixel(canvas, 50,25, 0,255,0,255);1780 });1781 it("2d.path.roundrect.end.1", function () {1782 const canvas = createCanvas(100, 50);1783 const ctx = canvas.getContext("2d");1784 const t = new Test();1785 ctx.fillStyle = '#f00';1786 ctx.fillRect(0, 0, 100, 50);1787 ctx.strokeStyle = '#0f0';1788 ctx.lineWidth = 100;1789 ctx.roundRect(200, 100, 400, 1000, [0]);1790 ctx.lineTo(-2000, -1000);1791 ctx.stroke();1792 _assertPixel(canvas, 50,25, 0,255,0,255);1793 });1794 it("2d.path.roundrect.end.2", function () {1795 const canvas = createCanvas(100, 50);1796 const ctx = canvas.getContext("2d");1797 const t = new Test();1798 ctx.fillStyle = '#f00';1799 ctx.fillRect(0, 0, 100, 50);1800 ctx.strokeStyle = '#0f0';1801 ctx.lineWidth = 450;1802 ctx.lineCap = 'round';1803 ctx.lineJoin = 'bevel';1804 ctx.roundRect(150, 150, 2000, 2000, [0]);1805 ctx.lineTo(160, 160);1806 ctx.stroke();1807 _assertPixel(canvas, 1,1, 0,255,0,255);1808 _assertPixel(canvas, 98,1, 0,255,0,255);1809 _assertPixel(canvas, 1,48, 0,255,0,255);1810 _assertPixel(canvas, 98,48, 0,255,0,255);1811 });1812 it("2d.path.roundrect.end.3", function () {1813 const canvas = createCanvas(100, 50);1814 const ctx = canvas.getContext("2d");1815 const t = new Test();1816 ctx.fillStyle = '#f00';1817 ctx.fillRect(0, 0, 100, 50);1818 ctx.strokeStyle = '#0f0';1819 ctx.lineWidth = 100;1820 ctx.roundRect(101, 51, 2000, 2000, [500, 500, 500, 500]);1821 ctx.lineTo(-1, -1);1822 ctx.stroke();1823 _assertPixel(canvas, 1,1, 0,255,0,255);1824 _assertPixel(canvas, 98,1, 0,255,0,255);1825 _assertPixel(canvas, 1,48, 0,255,0,255);1826 _assertPixel(canvas, 98,48, 0,255,0,255);1827 });1828 it("2d.path.roundrect.end.4", function () {1829 const canvas = createCanvas(100, 50);1830 const ctx = canvas.getContext("2d");1831 const t = new Test();1832 ctx.fillStyle = '#0f0';1833 ctx.fillRect(0, 0, 100, 50);1834 ctx.strokeStyle = '#f00';1835 ctx.lineWidth = 10;1836 ctx.roundRect(-1, -1, 2000, 2000, [1000, 1000, 1000, 1000]);1837 ctx.lineTo(-150, -150);1838 ctx.stroke();1839 _assertPixel(canvas, 1,1, 0,255,0,255);1840 _assertPixel(canvas, 98,1, 0,255,0,255);1841 _assertPixel(canvas, 1,48, 0,255,0,255);1842 _assertPixel(canvas, 98,48, 0,255,0,255);1843 });1844 it("2d.path.roundrect.zero.1", function () {1845 const canvas = createCanvas(100, 50);1846 const ctx = canvas.getContext("2d");1847 const t = new Test();1848 ctx.fillStyle = '#f00';1849 ctx.fillRect(0, 0, 100, 50);1850 ctx.strokeStyle = '#0f0';1851 ctx.lineWidth = 100;1852 ctx.beginPath();1853 ctx.roundRect(0, 50, 100, 0, [0]);1854 ctx.stroke();1855 _assertPixel(canvas, 50,25, 0,255,0,255);1856 });1857 it("2d.path.roundrect.zero.2", function () {1858 const canvas = createCanvas(100, 50);1859 const ctx = canvas.getContext("2d");1860 const t = new Test();1861 ctx.fillStyle = '#f00';1862 ctx.fillRect(0, 0, 100, 50);1863 ctx.strokeStyle = '#0f0';1864 ctx.lineWidth = 100;1865 ctx.beginPath();1866 ctx.roundRect(50, -100, 0, 250, [0]);1867 ctx.stroke();1868 _assertPixel(canvas, 50,25, 0,255,0,255);1869 });1870 it("2d.path.roundrect.zero.3", function () {1871 const canvas = createCanvas(100, 50);1872 const ctx = canvas.getContext("2d");1873 const t = new Test();1874 ctx.fillStyle = '#0f0';1875 ctx.fillRect(0, 0, 100, 50);1876 ctx.strokeStyle = '#f00';1877 ctx.lineWidth = 100;1878 ctx.beginPath();1879 ctx.roundRect(50, 25, 0, 0, [0]);1880 ctx.stroke();1881 _assertPixel(canvas, 50,25, 0,255,0,255);1882 });1883 it("2d.path.roundrect.zero.4", function () {1884 const canvas = createCanvas(100, 50);1885 const ctx = canvas.getContext("2d");1886 const t = new Test();1887 ctx.fillStyle = '#f00';1888 ctx.fillRect(0, 0, 100, 50);1889 ctx.strokeStyle = '#0f0';1890 ctx.lineWidth = 50;1891 ctx.roundRect(100, 25, 0, 0, [0]);1892 ctx.lineTo(0, 25);1893 ctx.stroke();1894 _assertPixel(canvas, 50,25, 0,255,0,255);1895 });1896 it("2d.path.roundrect.zero.5", function () {1897 const canvas = createCanvas(100, 50);1898 const ctx = canvas.getContext("2d");1899 const t = new Test();1900 ctx.fillStyle = '#0f0';1901 ctx.fillRect(0, 0, 100, 50);1902 ctx.strokeStyle = '#f00';1903 ctx.lineWidth = 50;1904 ctx.moveTo(0, 0);1905 ctx.roundRect(100, 25, 0, 0, [0]);1906 ctx.stroke();1907 _assertPixel(canvas, 50,25, 0,255,0,255);1908 });1909 it("2d.path.roundrect.zero.6", function () {1910 const canvas = createCanvas(100, 50);1911 const ctx = canvas.getContext("2d");1912 const t = new Test();1913 ctx.fillStyle = '#0f0';1914 ctx.fillRect(0, 0, 100, 50);1915 ctx.strokeStyle = '#f00';1916 ctx.lineJoin = 'miter';1917 ctx.miterLimit = 1.5;1918 ctx.lineWidth = 200;1919 ctx.beginPath();1920 ctx.roundRect(100, 25, 1000, 0, [0]);1921 ctx.stroke();1922 _assertPixel(canvas, 50,25, 0,255,0,255);1923 });1924 it("2d.path.roundrect.negative", function () {1925 const canvas = createCanvas(100, 50);1926 const ctx = canvas.getContext("2d");1927 const t = new Test();1928 ctx.fillStyle = '#f00';1929 ctx.fillRect(0, 0, 100, 50);1930 ctx.beginPath();1931 ctx.fillStyle = '#0f0';1932 ctx.roundRect(0, 0, 50, 25, [10, 0, 0, 0]);1933 ctx.roundRect(100, 0, -50, 25, [10, 0, 0, 0]);1934 ctx.roundRect(0, 50, 50, -25, [10, 0, 0, 0]);1935 ctx.roundRect(100, 50, -50, -25, [10, 0, 0, 0]);1936 ctx.fill();1937 // All rects drawn1938 _assertPixel(canvas, 25,12, 0,255,0,255);1939 _assertPixel(canvas, 75,12, 0,255,0,255);1940 _assertPixel(canvas, 25,37, 0,255,0,255);1941 _assertPixel(canvas, 75,37, 0,255,0,255);1942 // Correct corners are rounded.1943 _assertPixel(canvas, 1,1, 255,0,0,255);1944 _assertPixel(canvas, 98,1, 255,0,0,255);1945 _assertPixel(canvas, 1,48, 255,0,0,255);1946 _assertPixel(canvas, 98,48, 255,0,0,255);1947 });1948 it("2d.path.roundrect.winding", function () {1949 const canvas = createCanvas(100, 50);1950 const ctx = canvas.getContext("2d");1951 const t = new Test();1952 ctx.fillStyle = '#0f0';1953 ctx.fillRect(0, 0, 100, 50);1954 ctx.beginPath();1955 ctx.fillStyle = '#f00';1956 ctx.roundRect(0, 0, 50, 50, [0]);1957 ctx.roundRect(100, 50, -50, -50, [0]);1958 ctx.roundRect(0, 25, 100, -25, [0]);1959 ctx.roundRect(100, 25, -100, 25, [0]);1960 ctx.fill();1961 _assertPixel(canvas, 25,12, 0,255,0,255);1962 _assertPixel(canvas, 75,12, 0,255,0,255);1963 _assertPixel(canvas, 25,37, 0,255,0,255);1964 _assertPixel(canvas, 75,37, 0,255,0,255);1965 });1966 it("2d.path.roundrect.selfintersect", function () {1967 const canvas = createCanvas(100, 50);1968 const ctx = canvas.getContext("2d");1969 const t = new Test();1970 ctx.fillStyle = '#f00';1971 ctx.roundRect(0, 0, 100, 50, [0]);1972 ctx.strokeStyle = '#0f0';1973 ctx.lineWidth = 90;1974 ctx.beginPath();1975 ctx.roundRect(45, 20, 10, 10, [0]);1976 ctx.stroke();1977 _assertPixel(canvas, 50,25, 0,255,0,255);1978 });1979 it("2d.path.roundrect.nonfinite", function () {1980 // roundRect() with Infinity/NaN is ignored1981 const canvas = createCanvas(100, 50);1982 const ctx = canvas.getContext("2d");1983 const t = new Test();1984 ctx.fillStyle = '#f00';1985 ctx.fillRect(0, 0, 100, 50)1986 ctx.moveTo(0, 0);1987 ctx.lineTo(100, 0);1988 ctx.roundRect(Infinity, 50, 1, 1, [0]);1989 ctx.roundRect(-Infinity, 50, 1, 1, [0]);1990 ctx.roundRect(NaN, 50, 1, 1, [0]);1991 ctx.roundRect(0, Infinity, 1, 1, [0]);1992 ctx.roundRect(0, -Infinity, 1, 1, [0]);1993 ctx.roundRect(0, NaN, 1, 1, [0]);1994 ctx.roundRect(0, 50, Infinity, 1, [0]);1995 ctx.roundRect(0, 50, -Infinity, 1, [0]);1996 ctx.roundRect(0, 50, NaN, 1, [0]);1997 ctx.roundRect(0, 50, 1, Infinity, [0]);1998 ctx.roundRect(0, 50, 1, -Infinity, [0]);1999 ctx.roundRect(0, 50, 1, NaN, [0]);2000 ctx.roundRect(0, 50, 1, 1, [Infinity]);2001 ctx.roundRect(0, 50, 1, 1, [-Infinity]);2002 ctx.roundRect(0, 50, 1, 1, [NaN]);2003 ctx.roundRect(0, 50, 1, 1, [Infinity,0]);2004 ctx.roundRect(0, 50, 1, 1, [-Infinity,0]);2005 ctx.roundRect(0, 50, 1, 1, [NaN,0]);2006 ctx.roundRect(0, 50, 1, 1, [0,Infinity]);2007 ctx.roundRect(0, 50, 1, 1, [0,-Infinity]);2008 ctx.roundRect(0, 50, 1, 1, [0,NaN]);2009 ctx.roundRect(0, 50, 1, 1, [Infinity,0,0]);2010 ctx.roundRect(0, 50, 1, 1, [-Infinity,0,0]);2011 ctx.roundRect(0, 50, 1, 1, [NaN,0,0]);2012 ctx.roundRect(0, 50, 1, 1, [0,Infinity,0]);2013 ctx.roundRect(0, 50, 1, 1, [0,-Infinity,0]);2014 ctx.roundRect(0, 50, 1, 1, [0,NaN,0]);2015 ctx.roundRect(0, 50, 1, 1, [0,0,Infinity]);2016 ctx.roundRect(0, 50, 1, 1, [0,0,-Infinity]);2017 ctx.roundRect(0, 50, 1, 1, [0,0,NaN]);2018 ctx.roundRect(0, 50, 1, 1, [Infinity,0,0,0]);2019 ctx.roundRect(0, 50, 1, 1, [-Infinity,0,0,0]);2020 ctx.roundRect(0, 50, 1, 1, [NaN,0,0,0]);2021 ctx.roundRect(0, 50, 1, 1, [0,Infinity,0,0]);2022 ctx.roundRect(0, 50, 1, 1, [0,-Infinity,0,0]);2023 ctx.roundRect(0, 50, 1, 1, [0,NaN,0,0]);2024 ctx.roundRect(0, 50, 1, 1, [0,0,Infinity,0]);2025 ctx.roundRect(0, 50, 1, 1, [0,0,-Infinity,0]);2026 ctx.roundRect(0, 50, 1, 1, [0,0,NaN,0]);2027 ctx.roundRect(0, 50, 1, 1, [0,0,0,Infinity]);2028 ctx.roundRect(0, 50, 1, 1, [0,0,0,-Infinity]);2029 ctx.roundRect(0, 50, 1, 1, [0,0,0,NaN]);2030 ctx.roundRect(Infinity, Infinity, 1, 1, [0]);2031 ctx.roundRect(Infinity, Infinity, Infinity, 1, [0]);2032 ctx.roundRect(Infinity, Infinity, Infinity, Infinity, [0]);2033 ctx.roundRect(Infinity, Infinity, Infinity, Infinity, [Infinity]);2034 ctx.roundRect(Infinity, Infinity, Infinity, 1, [Infinity]);2035 ctx.roundRect(Infinity, Infinity, 1, Infinity, [0]);2036 ctx.roundRect(Infinity, Infinity, 1, Infinity, [Infinity]);2037 ctx.roundRect(Infinity, Infinity, 1, 1, [Infinity]);2038 ctx.roundRect(Infinity, 50, Infinity, 1, [0]);2039 ctx.roundRect(Infinity, 50, Infinity, Infinity, [0]);2040 ctx.roundRect(Infinity, 50, Infinity, Infinity, [Infinity]);2041 ctx.roundRect(Infinity, 50, Infinity, 1, [Infinity]);2042 ctx.roundRect(Infinity, 50, 1, Infinity, [0]);2043 ctx.roundRect(Infinity, 50, 1, Infinity, [Infinity]);2044 ctx.roundRect(Infinity, 50, 1, 1, [Infinity]);2045 ctx.roundRect(0, Infinity, Infinity, 1, [0]);2046 ctx.roundRect(0, Infinity, Infinity, Infinity, [0]);2047 ctx.roundRect(0, Infinity, Infinity, Infinity, [Infinity]);2048 ctx.roundRect(0, Infinity, Infinity, 1, [Infinity]);2049 ctx.roundRect(0, Infinity, 1, Infinity, [0]);2050 ctx.roundRect(0, Infinity, 1, Infinity, [Infinity]);2051 ctx.roundRect(0, Infinity, 1, 1, [Infinity]);2052 ctx.roundRect(0, 50, Infinity, Infinity, [0]);2053 ctx.roundRect(0, 50, Infinity, Infinity, [Infinity]);2054 ctx.roundRect(0, 50, Infinity, 1, [Infinity]);2055 ctx.roundRect(0, 50, 1, Infinity, [Infinity]);2056 ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, Infinity)]);2057 ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, -Infinity)]);2058 ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, NaN)]);2059 ctx.roundRect(0, 0, 100, 100, [new DOMPoint(Infinity, 10)]);2060 ctx.roundRect(0, 0, 100, 100, [new DOMPoint(-Infinity, 10)]);2061 ctx.roundRect(0, 0, 100, 100, [new DOMPoint(NaN, 10)]);2062 ctx.roundRect(0, 0, 100, 100, [{x: 10, y: Infinity}]);2063 ctx.roundRect(0, 0, 100, 100, [{x: 10, y: -Infinity}]);2064 ctx.roundRect(0, 0, 100, 100, [{x: 10, y: NaN}]);2065 ctx.roundRect(0, 0, 100, 100, [{x: Infinity, y: 10}]);2066 ctx.roundRect(0, 0, 100, 100, [{x: -Infinity, y: 10}]);2067 ctx.roundRect(0, 0, 100, 100, [{x: NaN, y: 10}]);2068 ctx.lineTo(100, 50);2069 ctx.lineTo(0, 50);2070 ctx.fillStyle = '#0f0';2071 ctx.fill();2072 _assertPixel(canvas, 50,25, 0,255,0,255);2073 _assertPixel(canvas, 90,45, 0,255,0,255);2074 });2075 it("2d.path.roundrect.4.radii.1.double", function () {2076 // Verify that when four radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.2077 const canvas = createCanvas(100, 50);2078 const ctx = canvas.getContext("2d");2079 const t = new Test();2080 ctx.fillStyle = '#f00';2081 ctx.fillRect(0, 0, 100, 50);2082 ctx.roundRect(0, 0, 100, 50, [20, 0, 0, 0]);2083 ctx.fillStyle = '#0f0';2084 ctx.fill();2085 _assertPixel(canvas, 1,1, 255,0,0,255);2086 _assertPixel(canvas, 98,1, 0,255,0,255);2087 _assertPixel(canvas, 98,48, 0,255,0,255);2088 _assertPixel(canvas, 1,48, 0,255,0,255);2089 });2090 it("2d.path.roundrect.4.radii.1.dompoint", function () {2091 // Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.2092 const canvas = createCanvas(100, 50);2093 const ctx = canvas.getContext("2d");2094 const t = new Test();2095 ctx.fillStyle = '#f00';2096 ctx.fillRect(0, 0, 100, 50);2097 ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0, 0, 0]);2098 ctx.fillStyle = '#0f0';2099 ctx.fill();2100 2101 // top-left corner2102 _assertPixel(canvas, 20,1, 255,0,0,255);2103 _assertPixel(canvas, 41,1, 0,255,0,255);2104 _assertPixel(canvas, 1,10, 255,0,0,255);2105 _assertPixel(canvas, 1,21, 0,255,0,255);2106 2107 // other corners2108 _assertPixel(canvas, 98,1, 0,255,0,255);2109 _assertPixel(canvas, 98,48, 0,255,0,255);2110 _assertPixel(canvas, 1,48, 0,255,0,255);2111 });2112 it("2d.path.roundrect.4.radii.1.dompointinit", function () {2113 // Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.2114 const canvas = createCanvas(100, 50);2115 const ctx = canvas.getContext("2d");2116 const t = new Test();2117 ctx.fillStyle = '#f00';2118 ctx.fillRect(0, 0, 100, 50);2119 ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0, 0]);2120 ctx.fillStyle = '#0f0';2121 ctx.fill();2122 2123 // top-left corner2124 _assertPixel(canvas, 20,1, 255,0,0,255);2125 _assertPixel(canvas, 41,1, 0,255,0,255);2126 _assertPixel(canvas, 1,10, 255,0,0,255);2127 _assertPixel(canvas, 1,21, 0,255,0,255);2128 2129 // other corners2130 _assertPixel(canvas, 98,1, 0,255,0,255);2131 _assertPixel(canvas, 98,48, 0,255,0,255);2132 _assertPixel(canvas, 1,48, 0,255,0,255);2133 });2134 it("2d.path.roundrect.4.radii.2.double", function () {2135 // Verify that when four radii are given to roundRect(), the second radius, specified as a double, applies to the top-right corner.2136 const canvas = createCanvas(100, 50);2137 const ctx = canvas.getContext("2d");2138 const t = new Test();2139 ctx.fillStyle = '#f00';2140 ctx.fillRect(0, 0, 100, 50);2141 ctx.roundRect(0, 0, 100, 50, [0, 20, 0, 0]);2142 ctx.fillStyle = '#0f0';2143 ctx.fill();2144 _assertPixel(canvas, 1,1, 0,255,0,255);2145 _assertPixel(canvas, 98,1, 255,0,0,255);2146 _assertPixel(canvas, 98,48, 0,255,0,255);2147 _assertPixel(canvas, 1,48, 0,255,0,255);2148 });2149 it("2d.path.roundrect.4.radii.2.dompoint", function () {2150 // Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right corner.2151 const canvas = createCanvas(100, 50);2152 const ctx = canvas.getContext("2d");2153 const t = new Test();2154 ctx.fillStyle = '#f00';2155 ctx.fillRect(0, 0, 100, 50);2156 ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20), 0, 0]);2157 ctx.fillStyle = '#0f0';2158 ctx.fill();2159 2160 // top-right corner2161 _assertPixel(canvas, 79,1, 255,0,0,255);2162 _assertPixel(canvas, 58,1, 0,255,0,255);2163 _assertPixel(canvas, 98,10, 255,0,0,255);2164 _assertPixel(canvas, 98,21, 0,255,0,255);2165 2166 // other corners2167 _assertPixel(canvas, 1,1, 0,255,0,255);2168 _assertPixel(canvas, 98,48, 0,255,0,255);2169 _assertPixel(canvas, 1,48, 0,255,0,255);2170 });2171 it("2d.path.roundrect.4.radii.2.dompointinit", function () {2172 // Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner.2173 const canvas = createCanvas(100, 50);2174 const ctx = canvas.getContext("2d");2175 const t = new Test();2176 ctx.fillStyle = '#f00';2177 ctx.fillRect(0, 0, 100, 50);2178 ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0, 0]);2179 ctx.fillStyle = '#0f0';2180 ctx.fill();2181 2182 // top-right corner2183 _assertPixel(canvas, 79,1, 255,0,0,255);2184 _assertPixel(canvas, 58,1, 0,255,0,255);2185 _assertPixel(canvas, 98,10, 255,0,0,255);2186 _assertPixel(canvas, 98,21, 0,255,0,255);2187 2188 // other corners2189 _assertPixel(canvas, 1,1, 0,255,0,255);2190 _assertPixel(canvas, 98,48, 0,255,0,255);2191 _assertPixel(canvas, 1,48, 0,255,0,255);2192 });2193 it("2d.path.roundrect.4.radii.3.double", function () {2194 // Verify that when four radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.2195 const canvas = createCanvas(100, 50);2196 const ctx = canvas.getContext("2d");2197 const t = new Test();2198 ctx.fillStyle = '#f00';2199 ctx.fillRect(0, 0, 100, 50);2200 ctx.roundRect(0, 0, 100, 50, [0, 0, 20, 0]);2201 ctx.fillStyle = '#0f0';2202 ctx.fill();2203 _assertPixel(canvas, 1,1, 0,255,0,255);2204 _assertPixel(canvas, 98,1, 0,255,0,255);2205 _assertPixel(canvas, 98,48, 255,0,0,255);2206 _assertPixel(canvas, 1,48, 0,255,0,255);2207 });2208 it("2d.path.roundrect.4.radii.3.dompoint", function () {2209 // Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.2210 const canvas = createCanvas(100, 50);2211 const ctx = canvas.getContext("2d");2212 const t = new Test();2213 ctx.fillStyle = '#f00';2214 ctx.fillRect(0, 0, 100, 50);2215 ctx.roundRect(0, 0, 100, 50, [0, 0, new DOMPoint(40, 20), 0]);2216 ctx.fillStyle = '#0f0';2217 ctx.fill();2218 2219 // bottom-right corner2220 _assertPixel(canvas, 79,48, 255,0,0,255);2221 _assertPixel(canvas, 58,48, 0,255,0,255);2222 _assertPixel(canvas, 98,39, 255,0,0,255);2223 _assertPixel(canvas, 98,28, 0,255,0,255);2224 2225 // other corners2226 _assertPixel(canvas, 1,1, 0,255,0,255);2227 _assertPixel(canvas, 98,1, 0,255,0,255);2228 _assertPixel(canvas, 1,48, 0,255,0,255);2229 });2230 it("2d.path.roundrect.4.radii.3.dompointinit", function () {2231 // Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.2232 const canvas = createCanvas(100, 50);2233 const ctx = canvas.getContext("2d");2234 const t = new Test();2235 ctx.fillStyle = '#f00';2236 ctx.fillRect(0, 0, 100, 50);2237 ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}, 0]);2238 ctx.fillStyle = '#0f0';2239 ctx.fill();2240 2241 // bottom-right corner2242 _assertPixel(canvas, 79,48, 255,0,0,255);2243 _assertPixel(canvas, 58,48, 0,255,0,255);2244 _assertPixel(canvas, 98,39, 255,0,0,255);2245 _assertPixel(canvas, 98,28, 0,255,0,255);2246 2247 // other corners2248 _assertPixel(canvas, 1,1, 0,255,0,255);2249 _assertPixel(canvas, 98,1, 0,255,0,255);2250 _assertPixel(canvas, 1,48, 0,255,0,255);2251 });2252 it("2d.path.roundrect.4.radii.4.double", function () {2253 // Verify that when four radii are given to roundRect(), the fourth radius, specified as a double, applies to the bottom-left corner.2254 const canvas = createCanvas(100, 50);2255 const ctx = canvas.getContext("2d");2256 const t = new Test();2257 ctx.fillStyle = '#f00';2258 ctx.fillRect(0, 0, 100, 50);2259 ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 20]);2260 ctx.fillStyle = '#0f0';2261 ctx.fill();2262 _assertPixel(canvas, 1,1, 0,255,0,255);2263 _assertPixel(canvas, 98,1, 0,255,0,255);2264 _assertPixel(canvas, 98,48, 0,255,0,255);2265 _assertPixel(canvas, 1,48, 255,0,0,255);2266 });2267 it("2d.path.roundrect.4.radii.4.dompoint", function () {2268 // Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPoint, applies to the bottom-left corner.2269 const canvas = createCanvas(100, 50);2270 const ctx = canvas.getContext("2d");2271 const t = new Test();2272 ctx.fillStyle = '#f00';2273 ctx.fillRect(0, 0, 100, 50);2274 ctx.roundRect(0, 0, 100, 50, [0, 0, 0, new DOMPoint(40, 20)]);2275 ctx.fillStyle = '#0f0';2276 ctx.fill();2277 2278 // bottom-left corner2279 _assertPixel(canvas, 20,48, 255,0,0,255);2280 _assertPixel(canvas, 41,48, 0,255,0,255);2281 _assertPixel(canvas, 1,39, 255,0,0,255);2282 _assertPixel(canvas, 1,28, 0,255,0,255);2283 2284 // other corners2285 _assertPixel(canvas, 1,1, 0,255,0,255);2286 _assertPixel(canvas, 98,1, 0,255,0,255);2287 _assertPixel(canvas, 98,48, 0,255,0,255);2288 });2289 it("2d.path.roundrect.4.radii.4.dompointinit", function () {2290 // Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner.2291 const canvas = createCanvas(100, 50);2292 const ctx = canvas.getContext("2d");2293 const t = new Test();2294 ctx.fillStyle = '#f00';2295 ctx.fillRect(0, 0, 100, 50);2296 ctx.roundRect(0, 0, 100, 50, [0, 0, 0, {x: 40, y: 20}]);2297 ctx.fillStyle = '#0f0';2298 ctx.fill();2299 2300 // bottom-left corner2301 _assertPixel(canvas, 20,48, 255,0,0,255);2302 _assertPixel(canvas, 41,48, 0,255,0,255);2303 _assertPixel(canvas, 1,39, 255,0,0,255);2304 _assertPixel(canvas, 1,28, 0,255,0,255);2305 2306 // other corners2307 _assertPixel(canvas, 1,1, 0,255,0,255);2308 _assertPixel(canvas, 98,1, 0,255,0,255);2309 _assertPixel(canvas, 98,48, 0,255,0,255);2310 });2311 it("2d.path.roundrect.3.radii.1.double", function () {2312 // Verify that when three radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.2313 const canvas = createCanvas(100, 50);2314 const ctx = canvas.getContext("2d");2315 const t = new Test();2316 ctx.fillStyle = '#f00';2317 ctx.fillRect(0, 0, 100, 50);2318 ctx.roundRect(0, 0, 100, 50, [20, 0, 0]);2319 ctx.fillStyle = '#0f0';2320 ctx.fill();2321 _assertPixel(canvas, 1,1, 255,0,0,255);2322 _assertPixel(canvas, 98,1, 0,255,0,255);2323 _assertPixel(canvas, 98,48, 0,255,0,255);2324 _assertPixel(canvas, 1,48, 0,255,0,255);2325 });2326 it("2d.path.roundrect.3.radii.1.dompoint", function () {2327 // Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.2328 const canvas = createCanvas(100, 50);2329 const ctx = canvas.getContext("2d");2330 const t = new Test();2331 ctx.fillStyle = '#f00';2332 ctx.fillRect(0, 0, 100, 50);2333 ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0, 0]);2334 ctx.fillStyle = '#0f0';2335 ctx.fill();2336 2337 // top-left corner2338 _assertPixel(canvas, 20,1, 255,0,0,255);2339 _assertPixel(canvas, 41,1, 0,255,0,255);2340 _assertPixel(canvas, 1,10, 255,0,0,255);2341 _assertPixel(canvas, 1,21, 0,255,0,255);2342 2343 // other corners2344 _assertPixel(canvas, 98,1, 0,255,0,255);2345 _assertPixel(canvas, 98,48, 0,255,0,255);2346 _assertPixel(canvas, 1,48, 0,255,0,255);2347 });2348 it("2d.path.roundrect.3.radii.1.dompointinit", function () {2349 // Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.2350 const canvas = createCanvas(100, 50);2351 const ctx = canvas.getContext("2d");2352 const t = new Test();2353 ctx.fillStyle = '#f00';2354 ctx.fillRect(0, 0, 100, 50);2355 ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0]);2356 ctx.fillStyle = '#0f0';2357 ctx.fill();2358 2359 // top-left corner2360 _assertPixel(canvas, 20,1, 255,0,0,255);2361 _assertPixel(canvas, 41,1, 0,255,0,255);2362 _assertPixel(canvas, 1,10, 255,0,0,255);2363 _assertPixel(canvas, 1,21, 0,255,0,255);2364 2365 // other corners2366 _assertPixel(canvas, 98,1, 0,255,0,255);2367 _assertPixel(canvas, 98,48, 0,255,0,255);2368 _assertPixel(canvas, 1,48, 0,255,0,255);2369 });2370 it("2d.path.roundrect.3.radii.2.double", function () {2371 // Verify that when three radii are given to roundRect(), the second radius, specified as a double, applies to the top-right and bottom-left corners.2372 const canvas = createCanvas(100, 50);2373 const ctx = canvas.getContext("2d");2374 const t = new Test();2375 ctx.fillStyle = '#f00';2376 ctx.fillRect(0, 0, 100, 50);2377 ctx.roundRect(0, 0, 100, 50, [0, 20, 0]);2378 ctx.fillStyle = '#0f0';2379 ctx.fill();2380 _assertPixel(canvas, 1,1, 0,255,0,255);2381 _assertPixel(canvas, 98,1, 255,0,0,255);2382 _assertPixel(canvas, 98,48, 0,255,0,255);2383 _assertPixel(canvas, 1,48, 255,0,0,255);2384 });2385 it("2d.path.roundrect.3.radii.2.dompoint", function () {2386 // Verify that when three radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottom-left corners.2387 const canvas = createCanvas(100, 50);2388 const ctx = canvas.getContext("2d");2389 const t = new Test();2390 ctx.fillStyle = '#f00';2391 ctx.fillRect(0, 0, 100, 50);2392 ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20), 0]);2393 ctx.fillStyle = '#0f0';2394 ctx.fill();2395 2396 // top-right corner2397 _assertPixel(canvas, 79,1, 255,0,0,255);2398 _assertPixel(canvas, 58,1, 0,255,0,255);2399 _assertPixel(canvas, 98,10, 255,0,0,255);2400 _assertPixel(canvas, 98,21, 0,255,0,255);2401 2402 // bottom-left corner2403 _assertPixel(canvas, 20,48, 255,0,0,255);2404 _assertPixel(canvas, 41,48, 0,255,0,255);2405 _assertPixel(canvas, 1,39, 255,0,0,255);2406 _assertPixel(canvas, 1,28, 0,255,0,255);2407 2408 // other corners2409 _assertPixel(canvas, 1,1, 0,255,0,255);2410 _assertPixel(canvas, 98,48, 0,255,0,255);2411 });2412 it("2d.path.roundrect.3.radii.2.dompointinit", function () {2413 // Verify that when three radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottom-left corners.2414 const canvas = createCanvas(100, 50);2415 const ctx = canvas.getContext("2d");2416 const t = new Test();2417 ctx.fillStyle = '#f00';2418 ctx.fillRect(0, 0, 100, 50);2419 ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0]);2420 ctx.fillStyle = '#0f0';2421 ctx.fill();2422 2423 // top-right corner2424 _assertPixel(canvas, 79,1, 255,0,0,255);2425 _assertPixel(canvas, 58,1, 0,255,0,255);2426 _assertPixel(canvas, 98,10, 255,0,0,255);2427 _assertPixel(canvas, 98,21, 0,255,0,255);2428 2429 // bottom-left corner2430 _assertPixel(canvas, 20,48, 255,0,0,255);2431 _assertPixel(canvas, 41,48, 0,255,0,255);2432 _assertPixel(canvas, 1,39, 255,0,0,255);2433 _assertPixel(canvas, 1,28, 0,255,0,255);2434 2435 // other corners2436 _assertPixel(canvas, 1,1, 0,255,0,255);2437 _assertPixel(canvas, 98,48, 0,255,0,255);2438 });2439 it("2d.path.roundrect.3.radii.3.double", function () {2440 // Verify that when three radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.2441 const canvas = createCanvas(100, 50);2442 const ctx = canvas.getContext("2d");2443 const t = new Test();2444 ctx.fillStyle = '#f00';2445 ctx.fillRect(0, 0, 100, 50);2446 ctx.roundRect(0, 0, 100, 50, [0, 0, 20]);2447 ctx.fillStyle = '#0f0';2448 ctx.fill();2449 _assertPixel(canvas, 1,1, 0,255,0,255);2450 _assertPixel(canvas, 98,1, 0,255,0,255);2451 _assertPixel(canvas, 98,48, 255,0,0,255);2452 _assertPixel(canvas, 1,48, 0,255,0,255);2453 });2454 it("2d.path.roundrect.3.radii.3.dompoint", function () {2455 // Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.2456 const canvas = createCanvas(100, 50);2457 const ctx = canvas.getContext("2d");2458 const t = new Test();2459 ctx.fillStyle = '#f00';2460 ctx.fillRect(0, 0, 100, 50);2461 ctx.roundRect(0, 0, 100, 50, [0, 0, new DOMPoint(40, 20)]);2462 ctx.fillStyle = '#0f0';2463 ctx.fill();2464 2465 // bottom-right corner2466 _assertPixel(canvas, 79,48, 255,0,0,255);2467 _assertPixel(canvas, 58,48, 0,255,0,255);2468 _assertPixel(canvas, 98,39, 255,0,0,255);2469 _assertPixel(canvas, 98,28, 0,255,0,255);2470 2471 // other corners2472 _assertPixel(canvas, 1,1, 0,255,0,255);2473 _assertPixel(canvas, 98,1, 0,255,0,255);2474 _assertPixel(canvas, 1,48, 0,255,0,255);2475 });2476 it("2d.path.roundrect.3.radii.3.dompointinit", function () {2477 // Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.2478 const canvas = createCanvas(100, 50);2479 const ctx = canvas.getContext("2d");2480 const t = new Test();2481 ctx.fillStyle = '#f00';2482 ctx.fillRect(0, 0, 100, 50);2483 ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}]);2484 ctx.fillStyle = '#0f0';2485 ctx.fill();2486 2487 // bottom-right corner2488 _assertPixel(canvas, 79,48, 255,0,0,255);2489 _assertPixel(canvas, 58,48, 0,255,0,255);2490 _assertPixel(canvas, 98,39, 255,0,0,255);2491 _assertPixel(canvas, 98,28, 0,255,0,255);2492 2493 // other corners2494 _assertPixel(canvas, 1,1, 0,255,0,255);2495 _assertPixel(canvas, 98,1, 0,255,0,255);2496 _assertPixel(canvas, 1,48, 0,255,0,255);2497 });2498 it("2d.path.roundrect.2.radii.1.double", function () {2499 // Verify that when two radii are given to roundRect(), the first radius, specified as a double, applies to the top-left and bottom-right corners.2500 const canvas = createCanvas(100, 50);2501 const ctx = canvas.getContext("2d");2502 const t = new Test();2503 ctx.fillStyle = '#f00';2504 ctx.fillRect(0, 0, 100, 50);2505 ctx.roundRect(0, 0, 100, 50, [20, 0]);2506 ctx.fillStyle = '#0f0';2507 ctx.fill();2508 _assertPixel(canvas, 1,1, 255,0,0,255);2509 _assertPixel(canvas, 98,1, 0,255,0,255);2510 _assertPixel(canvas, 98,48, 255,0,0,255);2511 _assertPixel(canvas, 1,48, 0,255,0,255);2512 });2513 it("2d.path.roundrect.2.radii.1.dompoint", function () {2514 // Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left and bottom-right corners.2515 const canvas = createCanvas(100, 50);2516 const ctx = canvas.getContext("2d");2517 const t = new Test();2518 ctx.fillStyle = '#f00';2519 ctx.fillRect(0, 0, 100, 50);2520 ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0]);2521 ctx.fillStyle = '#0f0';2522 ctx.fill();2523 2524 // top-left corner2525 _assertPixel(canvas, 20,1, 255,0,0,255);2526 _assertPixel(canvas, 41,1, 0,255,0,255);2527 _assertPixel(canvas, 1,10, 255,0,0,255);2528 _assertPixel(canvas, 1,21, 0,255,0,255);2529 2530 // bottom-right corner2531 _assertPixel(canvas, 79,48, 255,0,0,255);2532 _assertPixel(canvas, 58,48, 0,255,0,255);2533 _assertPixel(canvas, 98,39, 255,0,0,255);2534 _assertPixel(canvas, 98,28, 0,255,0,255);2535 2536 // other corners2537 _assertPixel(canvas, 98,1, 0,255,0,255);2538 _assertPixel(canvas, 1,48, 0,255,0,255);2539 });2540 it("2d.path.roundrect.2.radii.1.dompointinit", function () {2541 // Verify that when two radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left and bottom-right corners.2542 const canvas = createCanvas(100, 50);2543 const ctx = canvas.getContext("2d");2544 const t = new Test();2545 ctx.fillStyle = '#f00';2546 ctx.fillRect(0, 0, 100, 50);2547 ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0]);2548 ctx.fillStyle = '#0f0';2549 ctx.fill();2550 2551 // top-left corner2552 _assertPixel(canvas, 20,1, 255,0,0,255);2553 _assertPixel(canvas, 41,1, 0,255,0,255);2554 _assertPixel(canvas, 1,10, 255,0,0,255);2555 _assertPixel(canvas, 1,21, 0,255,0,255);2556 2557 // bottom-right corner2558 _assertPixel(canvas, 79,48, 255,0,0,255);2559 _assertPixel(canvas, 58,48, 0,255,0,255);2560 _assertPixel(canvas, 98,39, 255,0,0,255);2561 _assertPixel(canvas, 98,28, 0,255,0,255);2562 2563 // other corners2564 _assertPixel(canvas, 98,1, 0,255,0,255);2565 _assertPixel(canvas, 1,48, 0,255,0,255);2566 });2567 it("2d.path.roundrect.2.radii.2.double", function () {2568 // Verify that when two radii are given to roundRect(), the second radius, specified as a double, applies to the top-right and bottom-left corners.2569 const canvas = createCanvas(100, 50);2570 const ctx = canvas.getContext("2d");2571 const t = new Test();2572 ctx.fillStyle = '#f00';2573 ctx.fillRect(0, 0, 100, 50);2574 ctx.roundRect(0, 0, 100, 50, [0, 20]);2575 ctx.fillStyle = '#0f0';2576 ctx.fill();2577 _assertPixel(canvas, 1,1, 0,255,0,255);2578 _assertPixel(canvas, 98,1, 255,0,0,255);2579 _assertPixel(canvas, 98,48, 0,255,0,255);2580 _assertPixel(canvas, 1,48, 255,0,0,255);2581 });2582 it("2d.path.roundrect.2.radii.2.dompoint", function () {2583 // Verify that when two radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right and bottom-left corners.2584 const canvas = createCanvas(100, 50);2585 const ctx = canvas.getContext("2d");2586 const t = new Test();2587 ctx.fillStyle = '#f00';2588 ctx.fillRect(0, 0, 100, 50);2589 ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20)]);2590 ctx.fillStyle = '#0f0';2591 ctx.fill();2592 2593 // top-right corner2594 _assertPixel(canvas, 79,1, 255,0,0,255);2595 _assertPixel(canvas, 58,1, 0,255,0,255);2596 _assertPixel(canvas, 98,10, 255,0,0,255);2597 _assertPixel(canvas, 98,21, 0,255,0,255);2598 2599 // bottom-left corner2600 _assertPixel(canvas, 20,48, 255,0,0,255);2601 _assertPixel(canvas, 41,48, 0,255,0,255);2602 _assertPixel(canvas, 1,39, 255,0,0,255);2603 _assertPixel(canvas, 1,28, 0,255,0,255);2604 2605 // other corners2606 _assertPixel(canvas, 1,1, 0,255,0,255);2607 _assertPixel(canvas, 98,48, 0,255,0,255);2608 });2609 it("2d.path.roundrect.2.radii.2.dompointinit", function () {2610 // Verify that when two radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right and bottom-left corners.2611 const canvas = createCanvas(100, 50);2612 const ctx = canvas.getContext("2d");2613 const t = new Test();2614 ctx.fillStyle = '#f00';2615 ctx.fillRect(0, 0, 100, 50);2616 ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}]);2617 ctx.fillStyle = '#0f0';2618 ctx.fill();2619 2620 // top-right corner2621 _assertPixel(canvas, 79,1, 255,0,0,255);2622 _assertPixel(canvas, 58,1, 0,255,0,255);2623 _assertPixel(canvas, 98,10, 255,0,0,255);2624 _assertPixel(canvas, 98,21, 0,255,0,255);2625 2626 // bottom-left corner2627 _assertPixel(canvas, 20,48, 255,0,0,255);2628 _assertPixel(canvas, 41,48, 0,255,0,255);2629 _assertPixel(canvas, 1,39, 255,0,0,255);2630 _assertPixel(canvas, 1,28, 0,255,0,255);2631 2632 // other corners2633 _assertPixel(canvas, 1,1, 0,255,0,255);2634 _assertPixel(canvas, 98,48, 0,255,0,255);2635 });2636 it("2d.path.roundrect.1.radius.double", function () {2637 // Verify that when one radius is given to roundRect(), specified as a double, it applies to all corners.2638 const canvas = createCanvas(100, 50);2639 const ctx = canvas.getContext("2d");2640 const t = new Test();2641 ctx.fillStyle = '#f00';2642 ctx.fillRect(0, 0, 100, 50);2643 ctx.roundRect(0, 0, 100, 50, [20]);2644 ctx.fillStyle = '#0f0';2645 ctx.fill();2646 _assertPixel(canvas, 1,1, 255,0,0,255);2647 _assertPixel(canvas, 98,1, 255,0,0,255);2648 _assertPixel(canvas, 98,48, 255,0,0,255);2649 _assertPixel(canvas, 1,48, 255,0,0,255);2650 });2651 it("2d.path.roundrect.1.radius.double.single.argument", function () {2652 // Verify that when one radius is given to roundRect() as a non-array argument, specified as a double, it applies to all corners.2653 const canvas = createCanvas(100, 50);2654 const ctx = canvas.getContext("2d");2655 const t = new Test();2656 ctx.fillStyle = '#f00';2657 ctx.fillRect(0, 0, 100, 50);2658 ctx.roundRect(0, 0, 100, 50, 20);2659 ctx.fillStyle = '#0f0';2660 ctx.fill();2661 _assertPixel(canvas, 1,1, 255,0,0,255);2662 _assertPixel(canvas, 98,1, 255,0,0,255);2663 _assertPixel(canvas, 98,48, 255,0,0,255);2664 _assertPixel(canvas, 1,48, 255,0,0,255);2665 });2666 it("2d.path.roundrect.1.radius.dompoint", function () {2667 // Verify that when one radius is given to roundRect(), specified as a DOMPoint, it applies to all corners.2668 const canvas = createCanvas(100, 50);2669 const ctx = canvas.getContext("2d");2670 const t = new Test();2671 ctx.fillStyle = '#f00';2672 ctx.fillRect(0, 0, 100, 50);2673 ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20)]);2674 ctx.fillStyle = '#0f0';2675 ctx.fill();2676 2677 // top-left corner2678 _assertPixel(canvas, 20,1, 255,0,0,255);2679 _assertPixel(canvas, 41,1, 0,255,0,255);2680 _assertPixel(canvas, 1,10, 255,0,0,255);2681 _assertPixel(canvas, 1,21, 0,255,0,255);2682 2683 // top-right corner2684 _assertPixel(canvas, 79,1, 255,0,0,255);2685 _assertPixel(canvas, 58,1, 0,255,0,255);2686 _assertPixel(canvas, 98,10, 255,0,0,255);2687 _assertPixel(canvas, 98,21, 0,255,0,255);2688 2689 // bottom-right corner2690 _assertPixel(canvas, 79,48, 255,0,0,255);2691 _assertPixel(canvas, 58,48, 0,255,0,255);2692 _assertPixel(canvas, 98,39, 255,0,0,255);2693 _assertPixel(canvas, 98,28, 0,255,0,255);2694 2695 // bottom-left corner2696 _assertPixel(canvas, 20,48, 255,0,0,255);2697 _assertPixel(canvas, 41,48, 0,255,0,255);2698 _assertPixel(canvas, 1,39, 255,0,0,255);2699 _assertPixel(canvas, 1,28, 0,255,0,255);2700 });2701 it("2d.path.roundrect.1.radius.dompoint.single argument", function () {2702 // Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPoint, it applies to all corners.2703 const canvas = createCanvas(100, 50);2704 const ctx = canvas.getContext("2d");2705 const t = new Test();2706 ctx.fillStyle = '#f00';2707 ctx.fillRect(0, 0, 100, 50);2708 ctx.roundRect(0, 0, 100, 50, new DOMPoint(40, 20));2709 ctx.fillStyle = '#0f0';2710 ctx.fill();2711 2712 // top-left corner2713 _assertPixel(canvas, 20,1, 255,0,0,255);2714 _assertPixel(canvas, 41,1, 0,255,0,255);2715 _assertPixel(canvas, 1,10, 255,0,0,255);2716 _assertPixel(canvas, 1,21, 0,255,0,255);2717 2718 // top-right corner2719 _assertPixel(canvas, 79,1, 255,0,0,255);2720 _assertPixel(canvas, 58,1, 0,255,0,255);2721 _assertPixel(canvas, 98,10, 255,0,0,255);2722 _assertPixel(canvas, 98,21, 0,255,0,255);2723 2724 // bottom-right corner2725 _assertPixel(canvas, 79,48, 255,0,0,255);2726 _assertPixel(canvas, 58,48, 0,255,0,255);2727 _assertPixel(canvas, 98,39, 255,0,0,255);2728 _assertPixel(canvas, 98,28, 0,255,0,255);2729 2730 // bottom-left corner2731 _assertPixel(canvas, 20,48, 255,0,0,255);2732 _assertPixel(canvas, 41,48, 0,255,0,255);2733 _assertPixel(canvas, 1,39, 255,0,0,255);2734 _assertPixel(canvas, 1,28, 0,255,0,255);2735 });2736 it("2d.path.roundrect.1.radius.dompointinit", function () {2737 // Verify that when one radius is given to roundRect(), specified as a DOMPointInit, applies to all corners.2738 const canvas = createCanvas(100, 50);2739 const ctx = canvas.getContext("2d");2740 const t = new Test();2741 ctx.fillStyle = '#f00';2742 ctx.fillRect(0, 0, 100, 50);2743 ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}]);2744 ctx.fillStyle = '#0f0';2745 ctx.fill();2746 2747 // top-left corner2748 _assertPixel(canvas, 20,1, 255,0,0,255);2749 _assertPixel(canvas, 41,1, 0,255,0,255);2750 _assertPixel(canvas, 1,10, 255,0,0,255);2751 _assertPixel(canvas, 1,21, 0,255,0,255);2752 2753 // top-right corner2754 _assertPixel(canvas, 79,1, 255,0,0,255);2755 _assertPixel(canvas, 58,1, 0,255,0,255);2756 _assertPixel(canvas, 98,10, 255,0,0,255);2757 _assertPixel(canvas, 98,21, 0,255,0,255);2758 2759 // bottom-right corner2760 _assertPixel(canvas, 79,48, 255,0,0,255);2761 _assertPixel(canvas, 58,48, 0,255,0,255);2762 _assertPixel(canvas, 98,39, 255,0,0,255);2763 _assertPixel(canvas, 98,28, 0,255,0,255);2764 2765 // bottom-left corner2766 _assertPixel(canvas, 20,48, 255,0,0,255);2767 _assertPixel(canvas, 41,48, 0,255,0,255);2768 _assertPixel(canvas, 1,39, 255,0,0,255);2769 _assertPixel(canvas, 1,28, 0,255,0,255);2770 });2771 it("2d.path.roundrect.1.radius.dompointinit.single.argument", function () {2772 // Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPointInit, applies to all corners.2773 const canvas = createCanvas(100, 50);2774 const ctx = canvas.getContext("2d");2775 const t = new Test();2776 ctx.fillStyle = '#f00';2777 ctx.fillRect(0, 0, 100, 50);2778 ctx.roundRect(0, 0, 100, 50, {x: 40, y: 20});2779 ctx.fillStyle = '#0f0';2780 ctx.fill();2781 2782 // top-left corner2783 _assertPixel(canvas, 20,1, 255,0,0,255);2784 _assertPixel(canvas, 41,1, 0,255,0,255);2785 _assertPixel(canvas, 1,10, 255,0,0,255);2786 _assertPixel(canvas, 1,21, 0,255,0,255);2787 2788 // top-right corner2789 _assertPixel(canvas, 79,1, 255,0,0,255);2790 _assertPixel(canvas, 58,1, 0,255,0,255);2791 _assertPixel(canvas, 98,10, 255,0,0,255);2792 _assertPixel(canvas, 98,21, 0,255,0,255);2793 2794 // bottom-right corner2795 _assertPixel(canvas, 79,48, 255,0,0,255);2796 _assertPixel(canvas, 58,48, 0,255,0,255);2797 _assertPixel(canvas, 98,39, 255,0,0,255);2798 _assertPixel(canvas, 98,28, 0,255,0,255);2799 2800 // bottom-left corner2801 _assertPixel(canvas, 20,48, 255,0,0,255);2802 _assertPixel(canvas, 41,48, 0,255,0,255);2803 _assertPixel(canvas, 1,39, 255,0,0,255);2804 _assertPixel(canvas, 1,28, 0,255,0,255);2805 });2806 it("2d.path.roundrect.radius.intersecting.1", function () {2807 // Check that roundRects with intersecting corner arcs are rendered correctly.2808 const canvas = createCanvas(100, 50);2809 const ctx = canvas.getContext("2d");2810 const t = new Test();2811 ctx.fillStyle = '#f00';2812 ctx.fillRect(0, 0, 100, 50);2813 ctx.roundRect(0, 0, 100, 50, [40, 40, 40, 40]);2814 ctx.fillStyle = '#0f0';2815 ctx.fill();2816 _assertPixel(canvas, 2,25, 0,255,0,255);2817 _assertPixel(canvas, 50,1, 0,255,0,255);2818 _assertPixel(canvas, 50,25, 0,255,0,255);2819 _assertPixel(canvas, 50,48, 0,255,0,255);2820 _assertPixel(canvas, 97,25, 0,255,0,255);2821 _assertPixel(canvas, 1,1, 255,0,0,255);2822 _assertPixel(canvas, 98,1, 255,0,0,255);2823 _assertPixel(canvas, 1,48, 255,0,0,255);2824 _assertPixel(canvas, 98,48, 255,0,0,255);2825 });2826 it("2d.path.roundrect.radius.intersecting.2", function () {2827 // Check that roundRects with intersecting corner arcs are rendered correctly.2828 const canvas = createCanvas(100, 50);2829 const ctx = canvas.getContext("2d");2830 const t = new Test();2831 ctx.fillStyle = '#f00';2832 ctx.fillRect(0, 0, 100, 50);2833 ctx.roundRect(0, 0, 100, 50, [1000, 1000, 1000, 1000]);2834 ctx.fillStyle = '#0f0';2835 ctx.fill();2836 _assertPixel(canvas, 2,25, 0,255,0,255);2837 _assertPixel(canvas, 50,1, 0,255,0,255);2838 _assertPixel(canvas, 50,25, 0,255,0,255);2839 _assertPixel(canvas, 50,48, 0,255,0,255);2840 _assertPixel(canvas, 97,25, 0,255,0,255);2841 _assertPixel(canvas, 1,1, 255,0,0,255);2842 _assertPixel(canvas, 98,1, 255,0,0,255);2843 _assertPixel(canvas, 1,48, 255,0,0,255);2844 _assertPixel(canvas, 98,48, 255,0,0,255);2845 });2846 it("2d.path.roundrect.radius.none", function () {2847 // Check that roundRect throws an RangeError if radii is an empty array.2848 const canvas = createCanvas(100, 50);2849 const ctx = canvas.getContext("2d");2850 const t = new Test();2851 assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [])});2852 });2853 it("2d.path.roundrect.radius.noargument", function () {2854 // Check that roundRect draws a rectangle when no radii are provided.2855 const canvas = createCanvas(100, 50);2856 const ctx = canvas.getContext("2d");2857 const t = new Test();2858 ctx.fillStyle = '#f00';2859 ctx.fillRect(0, 0, 100, 50);2860 ctx.roundRect(10, 10, 80, 30);2861 ctx.fillStyle = '#0f0';2862 ctx.fill();2863 // upper left corner (10, 10)2864 _assertPixel(canvas, 10,9, 255,0,0,255);2865 _assertPixel(canvas, 9,10, 255,0,0,255);2866 _assertPixel(canvas, 10,10, 0,255,0,255);2867 2868 // upper right corner (89, 10)2869 _assertPixel(canvas, 90,10, 255,0,0,255);2870 _assertPixel(canvas, 89,9, 255,0,0,255);2871 _assertPixel(canvas, 89,10, 0,255,0,255);2872 2873 // lower right corner (89, 39)2874 _assertPixel(canvas, 89,40, 255,0,0,255);2875 _assertPixel(canvas, 90,39, 255,0,0,255);2876 _assertPixel(canvas, 89,39, 0,255,0,255);2877 2878 // lower left corner (10, 30)2879 _assertPixel(canvas, 9,39, 255,0,0,255);2880 _assertPixel(canvas, 10,40, 255,0,0,255);2881 _assertPixel(canvas, 10,39, 0,255,0,255);2882 });2883 it("2d.path.roundrect.radius.toomany", function () {2884 // Check that roundRect throws an IndeSizeError if radii has more than four items.2885 const canvas = createCanvas(100, 50);2886 const ctx = canvas.getContext("2d");2887 const t = new Test();2888 assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0])});2889 });2890 it("2d.path.roundrect.radius.negative", function () {2891 // roundRect() with negative radius throws an exception2892 const canvas = createCanvas(100, 50);2893 const ctx = canvas.getContext("2d");2894 const t = new Test();2895 assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [-1])});2896 assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [1, -1])});2897 assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [new DOMPoint(-1, 1), 1])});2898 assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [new DOMPoint(1, -1)])});2899 assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [{x: -1, y: 1}, 1])});2900 assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [{x: 1, y: -1}])});2901 });2902 it("2d.path.ellipse.basics", function () {2903 // Verify canvas throws error when drawing ellipse with negative radii.2904 const canvas = createCanvas(100, 50);2905 const ctx = canvas.getContext("2d");2906 const t = new Test();2907 ctx.ellipse(10, 10, 10, 5, 0, 0, 1, false);2908 ctx.ellipse(10, 10, 10, 0, 0, 0, 1, false);2909 ctx.ellipse(10, 10, -0, 5, 0, 0, 1, false);2910 assert.throws(function() { ctx.ellipse(10, 10, -2, 5, 0, 0, 1, false); }, /INDEX_SIZE_ERR/);2911 assert.throws(function() { ctx.ellipse(10, 10, 0, -1.5, 0, 0, 1, false); }, /INDEX_SIZE_ERR/);2912 assert.throws(function() { ctx.ellipse(10, 10, -2, -5, 0, 0, 1, false); }, /INDEX_SIZE_ERR/);2913 ctx.ellipse(80, 0, 10, 4294967277, Math.PI / -84, -Math.PI / 2147483436, false);2914 });2915 it("2d.path.fill.overlap", function () {2916 const canvas = createCanvas(100, 50);2917 const ctx = canvas.getContext("2d");2918 const t = new Test();2919 ctx.fillStyle = '#000';2920 ctx.fillRect(0, 0, 100, 50);2921 2922 ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';2923 ctx.rect(0, 0, 100, 50);2924 ctx.closePath();2925 ctx.rect(10, 10, 80, 30);2926 ctx.fill();2927 2928 _assertPixelApprox(canvas, 50,25, 0,127,0,255, 1);2929 });2930 it("2d.path.fill.winding.add", function () {2931 const canvas = createCanvas(100, 50);2932 const ctx = canvas.getContext("2d");2933 const t = new Test();2934 ctx.fillStyle = '#f00';2935 ctx.fillRect(0, 0, 100, 50);2936 2937 ctx.fillStyle = '#0f0';2938 ctx.moveTo(-10, -10);2939 ctx.lineTo(110, -10);2940 ctx.lineTo(110, 60);2941 ctx.lineTo(-10, 60);2942 ctx.lineTo(-10, -10);2943 ctx.lineTo(0, 0);2944 ctx.lineTo(100, 0);2945 ctx.lineTo(100, 50);2946 ctx.lineTo(0, 50);2947 ctx.fill();2948 2949 _assertPixel(canvas, 50,25, 0,255,0,255);2950 });2951 it("2d.path.fill.winding.subtract.1", function () {2952 const canvas = createCanvas(100, 50);2953 const ctx = canvas.getContext("2d");2954 const t = new Test();2955 ctx.fillStyle = '#0f0';2956 ctx.fillRect(0, 0, 100, 50);2957 2958 ctx.fillStyle = '#f00';2959 ctx.moveTo(-10, -10);2960 ctx.lineTo(110, -10);2961 ctx.lineTo(110, 60);2962 ctx.lineTo(-10, 60);2963 ctx.lineTo(-10, -10);2964 ctx.lineTo(0, 0);2965 ctx.lineTo(0, 50);2966 ctx.lineTo(100, 50);2967 ctx.lineTo(100, 0);2968 ctx.fill();2969 2970 _assertPixel(canvas, 50,25, 0,255,0,255);2971 });2972 it("2d.path.fill.winding.subtract.2", function () {2973 const canvas = createCanvas(100, 50);2974 const ctx = canvas.getContext("2d");2975 const t = new Test();2976 ctx.fillStyle = '#0f0';2977 ctx.fillRect(0, 0, 100, 50);2978 2979 ctx.fillStyle = '#f00';2980 ctx.moveTo(-10, -10);2981 ctx.lineTo(110, -10);2982 ctx.lineTo(110, 60);2983 ctx.lineTo(-10, 60);2984 ctx.moveTo(0, 0);2985 ctx.lineTo(0, 50);2986 ctx.lineTo(100, 50);2987 ctx.lineTo(100, 0);2988 ctx.fill();2989 2990 _assertPixel(canvas, 50,25, 0,255,0,255);2991 });2992 it("2d.path.fill.winding.subtract.3", function () {2993 const canvas = createCanvas(100, 50);2994 const ctx = canvas.getContext("2d");2995 const t = new Test();2996 ctx.fillStyle = '#f00';2997 ctx.fillRect(0, 0, 100, 50);2998 2999 ctx.fillStyle = '#0f0';3000 ctx.moveTo(-10, -10);3001 ctx.lineTo(110, -10);3002 ctx.lineTo(110, 60);3003 ctx.lineTo(-10, 60);3004 ctx.lineTo(-10, -10);3005 ctx.lineTo(-20, -20);3006 ctx.lineTo(120, -20);3007 ctx.lineTo(120, 70);3008 ctx.lineTo(-20, 70);3009 ctx.lineTo(-20, -20);3010 ctx.lineTo(0, 0);3011 ctx.lineTo(0, 50);3012 ctx.lineTo(100, 50);3013 ctx.lineTo(100, 0);3014 ctx.fill();3015 3016 _assertPixel(canvas, 50,25, 0,255,0,255);3017 });3018 it("2d.path.fill.closed.basic", function () {3019 const canvas = createCanvas(100, 50);3020 const ctx = canvas.getContext("2d");3021 const t = new Test();3022 ctx.fillStyle = '#f00';3023 ctx.fillRect(0, 0, 100, 50);3024 3025 ctx.fillStyle = '#0f0';3026 ctx.moveTo(0, 0);3027 ctx.lineTo(100, 0);3028 ctx.lineTo(100, 50);3029 ctx.lineTo(0, 50);3030 ctx.fill();3031 3032 _assertPixel(canvas, 50,25, 0,255,0,255);3033 });3034 it("2d.path.fill.closed.unaffected", function () {3035 const canvas = createCanvas(100, 50);3036 const ctx = canvas.getContext("2d");3037 const t = new Test();3038 ctx.fillStyle = '#00f';3039 ctx.fillRect(0, 0, 100, 50);3040 3041 ctx.moveTo(0, 0);3042 ctx.lineTo(100, 0);3043 ctx.lineTo(100, 50);3044 ctx.fillStyle = '#f00';3045 ctx.fill();3046 ctx.lineTo(0, 50);3047 ctx.fillStyle = '#0f0';3048 ctx.fill();3049 3050 _assertPixel(canvas, 90,10, 0,255,0,255);3051 _assertPixel(canvas, 10,40, 0,255,0,255);3052 });3053 it("2d.path.stroke.overlap", function () {3054 // Stroked subpaths are combined before being drawn3055 const canvas = createCanvas(100, 50);3056 const ctx = canvas.getContext("2d");3057 const t = new Test();3058 ctx.fillStyle = '#000';3059 ctx.fillRect(0, 0, 100, 50);3060 3061 ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';3062 ctx.lineWidth = 50;3063 ctx.moveTo(0, 20);3064 ctx.lineTo(100, 20);3065 ctx.moveTo(0, 30);3066 ctx.lineTo(100, 30);3067 ctx.stroke();3068 3069 _assertPixelApprox(canvas, 50,25, 0,127,0,255, 1);3070 });3071 it("2d.path.stroke.union", function () {3072 // Strokes in opposite directions are unioned, not subtracted3073 const canvas = createCanvas(100, 50);3074 const ctx = canvas.getContext("2d");3075 const t = new Test();3076 ctx.fillStyle = '#f00';3077 ctx.fillRect(0, 0, 100, 50);3078 3079 ctx.strokeStyle = '#0f0';3080 ctx.lineWidth = 40;3081 ctx.moveTo(0, 10);3082 ctx.lineTo(100, 10);3083 ctx.moveTo(100, 40);3084 ctx.lineTo(0, 40);3085 ctx.stroke();3086 3087 _assertPixel(canvas, 50,25, 0,255,0,255);3088 });3089 it("2d.path.stroke.unaffected", function () {3090 // Stroking does not start a new path or subpath3091 const canvas = createCanvas(100, 50);3092 const ctx = canvas.getContext("2d");3093 const t = new Test();3094 ctx.fillStyle = '#f00';3095 ctx.fillRect(0, 0, 100, 50);3096 3097 ctx.lineWidth = 50;3098 ctx.moveTo(-100, 25);3099 ctx.lineTo(-100, -100);3100 ctx.lineTo(200, -100);3101 ctx.lineTo(200, 25);3102 ctx.strokeStyle = '#f00';3103 ctx.stroke();3104 3105 ctx.closePath();3106 ctx.strokeStyle = '#0f0';3107 ctx.stroke();3108 3109 _assertPixel(canvas, 50,25, 0,255,0,255);3110 });3111 it("2d.path.stroke.scale1", function () {3112 // Stroke line widths are scaled by the current transformation matrix3113 const canvas = createCanvas(100, 50);3114 const ctx = canvas.getContext("2d");3115 const t = new Test();3116 ctx.fillStyle = '#f00';3117 ctx.fillRect(0, 0, 100, 50);3118 3119 ctx.beginPath();3120 ctx.rect(25, 12.5, 50, 25);3121 ctx.save();3122 ctx.scale(50, 25);3123 ctx.strokeStyle = '#0f0';3124 ctx.stroke();3125 ctx.restore();3126 3127 ctx.beginPath();3128 ctx.rect(-25, -12.5, 150, 75);3129 ctx.save();3130 ctx.scale(50, 25);3131 ctx.strokeStyle = '#f00';3132 ctx.stroke();3133 ctx.restore();3134 3135 _assertPixel(canvas, 0,0, 0,255,0,255);3136 _assertPixel(canvas, 50,0, 0,255,0,255);3137 _assertPixel(canvas, 99,0, 0,255,0,255);3138 _assertPixel(canvas, 0,25, 0,255,0,255);3139 _assertPixel(canvas, 50,25, 0,255,0,255);3140 _assertPixel(canvas, 99,25, 0,255,0,255);3141 _assertPixel(canvas, 0,49, 0,255,0,255);3142 _assertPixel(canvas, 50,49, 0,255,0,255);3143 _assertPixel(canvas, 99,49, 0,255,0,255);3144 });3145 it("2d.path.stroke.scale2", function () {3146 // Stroke line widths are scaled by the current transformation matrix3147 const canvas = createCanvas(100, 50);3148 const ctx = canvas.getContext("2d");3149 const t = new Test();3150 ctx.fillStyle = '#f00';3151 ctx.fillRect(0, 0, 100, 50);3152 3153 ctx.beginPath();3154 ctx.rect(25, 12.5, 50, 25);3155 ctx.save();3156 ctx.rotate(Math.PI/2);3157 ctx.scale(25, 50);3158 ctx.strokeStyle = '#0f0';3159 ctx.stroke();3160 ctx.restore();3161 3162 ctx.beginPath();3163 ctx.rect(-25, -12.5, 150, 75);3164 ctx.save();3165 ctx.rotate(Math.PI/2);3166 ctx.scale(25, 50);3167 ctx.strokeStyle = '#f00';3168 ctx.stroke();3169 ctx.restore();3170 3171 _assertPixel(canvas, 0,0, 0,255,0,255);3172 _assertPixel(canvas, 50,0, 0,255,0,255);3173 _assertPixel(canvas, 99,0, 0,255,0,255);3174 _assertPixel(canvas, 0,25, 0,255,0,255);3175 _assertPixel(canvas, 50,25, 0,255,0,255);3176 _assertPixel(canvas, 99,25, 0,255,0,255);3177 _assertPixel(canvas, 0,49, 0,255,0,255);3178 _assertPixel(canvas, 50,49, 0,255,0,255);3179 _assertPixel(canvas, 99,49, 0,255,0,255);3180 });3181 it("2d.path.stroke.skew", function () {3182 // Strokes lines are skewed by the current transformation matrix3183 const canvas = createCanvas(100, 50);3184 const ctx = canvas.getContext("2d");3185 const t = new Test();3186 ctx.fillStyle = '#f00';3187 ctx.fillRect(0, 0, 100, 50);3188 3189 ctx.save();3190 ctx.beginPath();3191 ctx.moveTo(49, -50);3192 ctx.lineTo(201, -50);3193 ctx.rotate(Math.PI/4);3194 ctx.scale(1, 283);3195 ctx.strokeStyle = '#0f0';3196 ctx.stroke();3197 ctx.restore();3198 3199 ctx.save();3200 ctx.beginPath();3201 ctx.translate(-150, 0);3202 ctx.moveTo(49, -50);3203 ctx.lineTo(199, -50);3204 ctx.rotate(Math.PI/4);3205 ctx.scale(1, 142);3206 ctx.strokeStyle = '#f00';3207 ctx.stroke();3208 ctx.restore();3209 3210 ctx.save();3211 ctx.beginPath();3212 ctx.translate(-150, 0);3213 ctx.moveTo(49, -50);3214 ctx.lineTo(199, -50);3215 ctx.rotate(Math.PI/4);3216 ctx.scale(1, 142);3217 ctx.strokeStyle = '#f00';3218 ctx.stroke();3219 ctx.restore();3220 3221 _assertPixel(canvas, 0,0, 0,255,0,255);3222 _assertPixel(canvas, 50,0, 0,255,0,255);3223 _assertPixel(canvas, 99,0, 0,255,0,255);3224 _assertPixel(canvas, 0,25, 0,255,0,255);3225 _assertPixel(canvas, 50,25, 0,255,0,255);3226 _assertPixel(canvas, 99,25, 0,255,0,255);3227 _assertPixel(canvas, 0,49, 0,255,0,255);3228 _assertPixel(canvas, 50,49, 0,255,0,255);3229 _assertPixel(canvas, 99,49, 0,255,0,255);3230 });3231 it("2d.path.stroke.empty", function () {3232 // Empty subpaths are not stroked3233 const canvas = createCanvas(100, 50);3234 const ctx = canvas.getContext("2d");3235 const t = new Test();3236 ctx.fillStyle = '#0f0';3237 ctx.fillRect(0, 0, 100, 50);3238 3239 ctx.strokeStyle = '#f00';3240 ctx.lineWidth = 100;3241 ctx.lineCap = 'round';3242 ctx.lineJoin = 'round';3243 3244 ctx.beginPath();3245 ctx.moveTo(40, 25);3246 ctx.moveTo(60, 25);3247 ctx.stroke();3248 3249 _assertPixel(canvas, 50,25, 0,255,0,255);3250 });3251 it("2d.path.stroke.prune.line", function () {3252 // Zero-length line segments from lineTo are removed before stroking3253 const canvas = createCanvas(100, 50);3254 const ctx = canvas.getContext("2d");3255 const t = new Test();3256 ctx.fillStyle = '#0f0';3257 ctx.fillRect(0, 0, 100, 50);3258 3259 ctx.strokeStyle = '#f00';3260 ctx.lineWidth = 100;3261 ctx.lineCap = 'round';3262 ctx.lineJoin = 'round';3263 3264 ctx.beginPath();3265 ctx.moveTo(50, 25);3266 ctx.lineTo(50, 25);3267 ctx.stroke();3268 3269 _assertPixel(canvas, 50,25, 0,255,0,255);3270 });3271 it("2d.path.stroke.prune.closed", function () {3272 // Zero-length line segments from closed paths are removed before stroking3273 const canvas = createCanvas(100, 50);3274 const ctx = canvas.getContext("2d");3275 const t = new Test();3276 ctx.fillStyle = '#0f0';3277 ctx.fillRect(0, 0, 100, 50);3278 3279 ctx.strokeStyle = '#f00';3280 ctx.lineWidth = 100;3281 ctx.lineCap = 'round';3282 ctx.lineJoin = 'round';3283 3284 ctx.beginPath();3285 ctx.moveTo(50, 25);3286 ctx.lineTo(50, 25);3287 ctx.closePath();3288 ctx.stroke();3289 3290 _assertPixel(canvas, 50,25, 0,255,0,255);3291 });3292 it("2d.path.stroke.prune.curve", function () {3293 // Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking3294 const canvas = createCanvas(100, 50);3295 const ctx = canvas.getContext("2d");3296 const t = new Test();3297 ctx.fillStyle = '#0f0';3298 ctx.fillRect(0, 0, 100, 50);3299 3300 ctx.strokeStyle = '#f00';3301 ctx.lineWidth = 100;3302 ctx.lineCap = 'round';3303 ctx.lineJoin = 'round';3304 3305 ctx.beginPath();3306 ctx.moveTo(50, 25);3307 ctx.quadraticCurveTo(50, 25, 50, 25);3308 ctx.stroke();3309 3310 ctx.beginPath();3311 ctx.moveTo(50, 25);3312 ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);3313 ctx.stroke();3314 3315 _assertPixel(canvas, 50,25, 0,255,0,255);3316 });3317 it("2d.path.stroke.prune.arc", function () {3318 // Zero-length line segments from arcTo and arc are removed before stroking3319 const canvas = createCanvas(100, 50);3320 const ctx = canvas.getContext("2d");3321 const t = new Test();3322 ctx.fillStyle = '#0f0';3323 ctx.fillRect(0, 0, 100, 50);3324 3325 ctx.strokeStyle = '#f00';3326 ctx.lineWidth = 100;3327 ctx.lineCap = 'round';3328 ctx.lineJoin = 'round';3329 3330 ctx.beginPath();3331 ctx.moveTo(50, 25);3332 ctx.arcTo(50, 25, 150, 25, 10);3333 ctx.stroke();3334 3335 ctx.beginPath();3336 ctx.moveTo(60, 25);3337 ctx.arc(50, 25, 10, 0, 0, false);3338 ctx.stroke();3339 3340 _assertPixel(canvas, 50,25, 0,255,0,255);3341 });3342 it("2d.path.stroke.prune.rect", function () {3343 // Zero-length line segments from rect and strokeRect are removed before stroking3344 const canvas = createCanvas(100, 50);3345 const ctx = canvas.getContext("2d");3346 const t = new Test();3347 ctx.fillStyle = '#0f0';3348 ctx.fillRect(0, 0, 100, 50);3349 3350 ctx.strokeStyle = '#f00';3351 ctx.lineWidth = 100;3352 ctx.lineCap = 'round';3353 ctx.lineJoin = 'round';3354 3355 ctx.beginPath();3356 ctx.rect(50, 25, 0, 0);3357 ctx.stroke();3358 3359 ctx.strokeRect(50, 25, 0, 0);3360 3361 _assertPixel(canvas, 50,25, 0,255,0,255);3362 });3363 it("2d.path.stroke.prune.corner", function () {3364 // Zero-length line segments are removed before stroking with miters3365 const canvas = createCanvas(100, 50);3366 const ctx = canvas.getContext("2d");3367 const t = new Test();3368 ctx.fillStyle = '#0f0';3369 ctx.fillRect(0, 0, 100, 50);3370 3371 ctx.strokeStyle = '#f00';3372 ctx.lineWidth = 400;3373 ctx.lineJoin = 'miter';3374 ctx.miterLimit = 1.4;3375 3376 ctx.beginPath();3377 ctx.moveTo(-1000, 200);3378 ctx.lineTo(-100, 200);3379 ctx.lineTo(-100, 200);3380 ctx.lineTo(-100, 200);3381 ctx.lineTo(-100, 1000);3382 ctx.stroke();3383 3384 _assertPixel(canvas, 50,25, 0,255,0,255);3385 });3386 it("2d.path.transformation.basic", function () {3387 const canvas = createCanvas(100, 50);3388 const ctx = canvas.getContext("2d");3389 const t = new Test();3390 ctx.fillStyle = '#f00';3391 ctx.fillRect(0, 0, 100, 50);3392 3393 ctx.translate(-100, 0);3394 ctx.rect(100, 0, 100, 50);3395 ctx.translate(0, -100);3396 ctx.fillStyle = '#0f0';3397 ctx.fill();3398 3399 _assertPixel(canvas, 50,25, 0,255,0,255);3400 });3401 it("2d.path.transformation.multiple", function () {3402 // Transformations are applied while building paths, not when drawing3403 const canvas = createCanvas(100, 50);3404 const ctx = canvas.getContext("2d");3405 const t = new Test();3406 ctx.fillStyle = '#0f0';3407 ctx.fillRect(0, 0, 100, 50);3408 3409 ctx.fillStyle = '#f00';3410 ctx.translate(-100, 0);3411 ctx.rect(0, 0, 100, 50);3412 ctx.fill();3413 ctx.translate(100, 0);3414 ctx.fill();3415 3416 ctx.beginPath();3417 ctx.strokeStyle = '#f00';3418 ctx.lineWidth = 50;3419 ctx.translate(0, -50);3420 ctx.moveTo(0, 25);3421 ctx.lineTo(100, 25);3422 ctx.stroke();3423 ctx.translate(0, 50);3424 ctx.stroke();3425 3426 _assertPixel(canvas, 50,25, 0,255,0,255);3427 });3428 it("2d.path.transformation.changing", function () {3429 // Transformations are applied while building paths, not when drawing3430 const canvas = createCanvas(100, 50);3431 const ctx = canvas.getContext("2d");3432 const t = new Test();3433 ctx.fillStyle = '#f00';3434 ctx.fillRect(0, 0, 100, 50);3435 ctx.fillStyle = '#0f0';3436 ctx.moveTo(0, 0);3437 ctx.translate(100, 0);3438 ctx.lineTo(0, 0);3439 ctx.translate(0, 50);3440 ctx.lineTo(0, 0);3441 ctx.translate(-100, 0);3442 ctx.lineTo(0, 0);3443 ctx.translate(1000, 1000);3444 ctx.rotate(Math.PI/2);3445 ctx.scale(0.1, 0.1);3446 ctx.fill();3447 3448 _assertPixel(canvas, 50,25, 0,255,0,255);3449 });3450 it("2d.path.clip.empty", function () {3451 const canvas = createCanvas(100, 50);3452 const ctx = canvas.getContext("2d");3453 const t = new Test();3454 ctx.fillStyle = '#0f0';3455 ctx.fillRect(0, 0, 100, 50);3456 3457 ctx.beginPath();3458 ctx.clip();3459 3460 ctx.fillStyle = '#f00';3461 ctx.fillRect(0, 0, 100, 50);3462 3463 _assertPixel(canvas, 50,25, 0,255,0,255);3464 });3465 it("2d.path.clip.basic.1", function () {3466 const canvas = createCanvas(100, 50);3467 const ctx = canvas.getContext("2d");3468 const t = new Test();3469 ctx.fillStyle = '#f00';3470 ctx.fillRect(0, 0, 100, 50);3471 3472 ctx.beginPath();3473 ctx.rect(0, 0, 100, 50);3474 ctx.clip();3475 3476 ctx.fillStyle = '#0f0';3477 ctx.fillRect(0, 0, 100, 50);3478 3479 _assertPixel(canvas, 50,25, 0,255,0,255);3480 });3481 it("2d.path.clip.basic.2", function () {3482 const canvas = createCanvas(100, 50);3483 const ctx = canvas.getContext("2d");3484 const t = new Test();3485 ctx.fillStyle = '#0f0';3486 ctx.fillRect(0, 0, 100, 50);3487 3488 ctx.beginPath();3489 ctx.rect(-100, 0, 100, 50);3490 ctx.clip();3491 3492 ctx.fillStyle = '#f00';3493 ctx.fillRect(0, 0, 100, 50);3494 3495 _assertPixel(canvas, 50,25, 0,255,0,255);3496 });3497 it("2d.path.clip.intersect", function () {3498 const canvas = createCanvas(100, 50);3499 const ctx = canvas.getContext("2d");3500 const t = new Test();3501 ctx.fillStyle = '#0f0';3502 ctx.fillRect(0, 0, 100, 50);3503 3504 ctx.beginPath();3505 ctx.rect(0, 0, 50, 50);3506 ctx.clip();3507 ctx.beginPath();3508 ctx.rect(50, 0, 50, 50)3509 ctx.clip();3510 3511 ctx.fillStyle = '#f00';3512 ctx.fillRect(0, 0, 100, 50);3513 3514 _assertPixel(canvas, 50,25, 0,255,0,255);3515 });3516 it("2d.path.clip.winding.1", function () {3517 const canvas = createCanvas(100, 50);3518 const ctx = canvas.getContext("2d");3519 const t = new Test();3520 ctx.fillStyle = '#0f0';3521 ctx.fillRect(0, 0, 100, 50);3522 3523 ctx.beginPath();3524 ctx.moveTo(-10, -10);3525 ctx.lineTo(110, -10);3526 ctx.lineTo(110, 60);3527 ctx.lineTo(-10, 60);3528 ctx.lineTo(-10, -10);3529 ctx.lineTo(0, 0);3530 ctx.lineTo(0, 50);3531 ctx.lineTo(100, 50);3532 ctx.lineTo(100, 0);3533 ctx.clip();3534 3535 ctx.fillStyle = '#f00';3536 ctx.fillRect(0, 0, 100, 50);3537 3538 _assertPixel(canvas, 50,25, 0,255,0,255);3539 });3540 it("2d.path.clip.winding.2", function () {3541 const canvas = createCanvas(100, 50);3542 const ctx = canvas.getContext("2d");3543 const t = new Test();3544 ctx.fillStyle = '#f00';3545 ctx.fillRect(0, 0, 100, 50);3546 3547 ctx.beginPath();3548 ctx.moveTo(-10, -10);3549 ctx.lineTo(110, -10);3550 ctx.lineTo(110, 60);3551 ctx.lineTo(-10, 60);3552 ctx.lineTo(-10, -10);3553 ctx.clip();3554 3555 ctx.beginPath();3556 ctx.moveTo(0, 0);3557 ctx.lineTo(0, 50);3558 ctx.lineTo(100, 50);3559 ctx.lineTo(100, 0);3560 ctx.lineTo(0, 0);3561 ctx.clip();3562 3563 ctx.fillStyle = '#0f0';3564 ctx.fillRect(0, 0, 100, 50);3565 3566 _assertPixel(canvas, 50,25, 0,255,0,255);3567 });3568 it("2d.path.clip.unaffected", function () {3569 const canvas = createCanvas(100, 50);3570 const ctx = canvas.getContext("2d");3571 const t = new Test();3572 ctx.fillStyle = '#f00';3573 ctx.fillRect(0, 0, 100, 50);3574 3575 ctx.fillStyle = '#0f0';3576 3577 ctx.beginPath();3578 ctx.moveTo(0, 0);3579 ctx.lineTo(0, 50);3580 ctx.lineTo(100, 50);3581 ctx.lineTo(100, 0);3582 ctx.clip();3583 3584 ctx.lineTo(0, 0);3585 ctx.fill();3586 3587 _assertPixel(canvas, 50,25, 0,255,0,255);3588 });3589 it("2d.path.isPointInPath.basic.1", function () {3590 // isPointInPath() detects whether the point is inside the path3591 const canvas = createCanvas(100, 50);3592 const ctx = canvas.getContext("2d");3593 const t = new Test();3594 ctx.rect(0, 0, 20, 20);3595 assert.strictEqual(ctx.isPointInPath(10, 10), true, "ctx.isPointInPath(10, 10)", "true")3596 assert.strictEqual(ctx.isPointInPath(30, 10), false, "ctx.isPointInPath(30, 10)", "false")3597 });3598 it("2d.path.isPointInPath.basic.2", function () {3599 // isPointInPath() detects whether the point is inside the path3600 const canvas = createCanvas(100, 50);3601 const ctx = canvas.getContext("2d");...
line-styles.js
Source:line-styles.js
...43 } else {44 assert.strictEqual(actual, expected);45 }46}47function _assertPixel(canvas, x, y, r, g, b, a, pos, color) {48 const c = _getPixel(canvas, x,y);49 assert.strictEqual(c[0], r, 'Red channel of the pixel at (' + x + ', ' + y + ')');50 assert.strictEqual(c[1], g, 'Green channel of the pixel at (' + x + ', ' + y + ')');51 assert.strictEqual(c[2], b, 'Blue channel of the pixel at (' + x + ', ' + y + ')');52 assert.strictEqual(c[3], a, 'Alpha channel of the pixel at (' + x + ', ' + y + ')');53}54function _assertPixelApprox(canvas, x, y, r, g, b, a, pos, color, tolerance) {55 const c = _getPixel(canvas, x,y);56 _assertApprox(c[0], r, tolerance, 'Red channel of the pixel at (' + x + ', ' + y + ')');57 _assertApprox(c[1], g, tolerance, 'Green channel of the pixel at (' + x + ', ' + y + ')');58 _assertApprox(c[2], b, tolerance, 'Blue channel of the pixel at (' + x + ', ' + y + ')');59 _assertApprox(c[3], a, tolerance, 'Alpha channel of the pixel at (' + x + ', ' + y + ')');60}61function assert_throws_js(Type, fn) {62 assert.throws(fn, Type);63}64// Used by font tests to allow fonts to load.65function deferTest() {}66class Test {67 // Two cases of this in the tests, look unnecessary.68 done() {}69 // Used by font tests to allow fonts to load.70 step_func_done(func) { func(); }71 // Used for image onload callback.72 step_func(func) { func(); }73}74function step_timeout(result, time) {75 // Nothing; code needs to be converted for this to work.76}77describe("WPT: line-styles", function () {78 it("2d.line.defaults", function () {79 const canvas = createCanvas(100, 50);80 const ctx = canvas.getContext("2d");81 const t = new Test();82 assert.strictEqual(ctx.lineWidth, 1, "ctx.lineWidth", "1")83 assert.strictEqual(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'")84 assert.strictEqual(ctx.lineJoin, 'miter', "ctx.lineJoin", "'miter'")85 assert.strictEqual(ctx.miterLimit, 10, "ctx.miterLimit", "10")86 });87 it("2d.line.width.basic", function () {88 // lineWidth determines the width of line strokes89 const canvas = createCanvas(100, 50);90 const ctx = canvas.getContext("2d");91 const t = new Test();92 ctx.fillStyle = '#0f0';93 ctx.fillRect(0, 0, 100, 50);94 95 ctx.lineWidth = 20;96 // Draw a green line over a red box, to check the line is not too small97 ctx.fillStyle = '#f00';98 ctx.strokeStyle = '#0f0';99 ctx.fillRect(15, 15, 20, 20);100 ctx.beginPath();101 ctx.moveTo(25, 15);102 ctx.lineTo(25, 35);103 ctx.stroke();104 105 // Draw a green box over a red line, to check the line is not too large106 ctx.fillStyle = '#0f0';107 ctx.strokeStyle = '#f00';108 ctx.beginPath();109 ctx.moveTo(75, 15);110 ctx.lineTo(75, 35);111 ctx.stroke();112 ctx.fillRect(65, 15, 20, 20);113 114 _assertPixel(canvas, 14,25, 0,255,0,255);115 _assertPixel(canvas, 15,25, 0,255,0,255);116 _assertPixel(canvas, 16,25, 0,255,0,255);117 _assertPixel(canvas, 25,25, 0,255,0,255);118 _assertPixel(canvas, 34,25, 0,255,0,255);119 _assertPixel(canvas, 35,25, 0,255,0,255);120 _assertPixel(canvas, 36,25, 0,255,0,255);121 122 _assertPixel(canvas, 64,25, 0,255,0,255);123 _assertPixel(canvas, 65,25, 0,255,0,255);124 _assertPixel(canvas, 66,25, 0,255,0,255);125 _assertPixel(canvas, 75,25, 0,255,0,255);126 _assertPixel(canvas, 84,25, 0,255,0,255);127 _assertPixel(canvas, 85,25, 0,255,0,255);128 _assertPixel(canvas, 86,25, 0,255,0,255);129 });130 it("2d.line.width.transformed", function () {131 // Line stroke widths are affected by scale transformations132 const canvas = createCanvas(100, 50);133 const ctx = canvas.getContext("2d");134 const t = new Test();135 ctx.fillStyle = '#0f0';136 ctx.fillRect(0, 0, 100, 50);137 138 ctx.lineWidth = 4;139 // Draw a green line over a red box, to check the line is not too small140 ctx.fillStyle = '#f00';141 ctx.strokeStyle = '#0f0';142 ctx.fillRect(15, 15, 20, 20);143 ctx.save();144 ctx.scale(5, 1);145 ctx.beginPath();146 ctx.moveTo(5, 15);147 ctx.lineTo(5, 35);148 ctx.stroke();149 ctx.restore();150 151 // Draw a green box over a red line, to check the line is not too large152 ctx.fillStyle = '#0f0';153 ctx.strokeStyle = '#f00';154 ctx.save();155 ctx.scale(-5, 1);156 ctx.beginPath();157 ctx.moveTo(-15, 15);158 ctx.lineTo(-15, 35);159 ctx.stroke();160 ctx.restore();161 ctx.fillRect(65, 15, 20, 20);162 163 _assertPixel(canvas, 14,25, 0,255,0,255);164 _assertPixel(canvas, 15,25, 0,255,0,255);165 _assertPixel(canvas, 16,25, 0,255,0,255);166 _assertPixel(canvas, 25,25, 0,255,0,255);167 _assertPixel(canvas, 34,25, 0,255,0,255);168 _assertPixel(canvas, 35,25, 0,255,0,255);169 _assertPixel(canvas, 36,25, 0,255,0,255);170 171 _assertPixel(canvas, 64,25, 0,255,0,255);172 _assertPixel(canvas, 65,25, 0,255,0,255);173 _assertPixel(canvas, 66,25, 0,255,0,255);174 _assertPixel(canvas, 75,25, 0,255,0,255);175 _assertPixel(canvas, 84,25, 0,255,0,255);176 _assertPixel(canvas, 85,25, 0,255,0,255);177 _assertPixel(canvas, 86,25, 0,255,0,255);178 });179 it("2d.line.width.scaledefault", function () {180 // Default lineWidth strokes are affected by scale transformations181 const canvas = createCanvas(100, 50);182 const ctx = canvas.getContext("2d");183 const t = new Test();184 ctx.fillStyle = '#f00';185 ctx.fillRect(0, 0, 100, 50);186 187 ctx.scale(50, 50);188 ctx.strokeStyle = '#0f0';189 ctx.moveTo(0, 0.5);190 ctx.lineTo(2, 0.5);191 ctx.stroke();192 193 _assertPixel(canvas, 25,25, 0,255,0,255);194 _assertPixel(canvas, 50,25, 0,255,0,255);195 _assertPixel(canvas, 75,25, 0,255,0,255);196 _assertPixel(canvas, 50,5, 0,255,0,255);197 _assertPixel(canvas, 50,45, 0,255,0,255);198 });199 it("2d.line.width.valid", function () {200 // Setting lineWidth to valid values works201 const canvas = createCanvas(100, 50);202 const ctx = canvas.getContext("2d");203 const t = new Test();204 ctx.lineWidth = 1.5;205 assert.strictEqual(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5")206 207 ctx.lineWidth = "1e1";208 assert.strictEqual(ctx.lineWidth, 10, "ctx.lineWidth", "10")209 210 ctx.lineWidth = 1/1024;211 assert.strictEqual(ctx.lineWidth, 1/1024, "ctx.lineWidth", "1/1024")212 213 ctx.lineWidth = 1000;214 assert.strictEqual(ctx.lineWidth, 1000, "ctx.lineWidth", "1000")215 });216 it("2d.line.width.invalid", function () {217 // Setting lineWidth to invalid values is ignored218 const canvas = createCanvas(100, 50);219 const ctx = canvas.getContext("2d");220 const t = new Test();221 ctx.lineWidth = 1.5;222 assert.strictEqual(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5")223 224 ctx.lineWidth = 1.5;225 ctx.lineWidth = 0;226 assert.strictEqual(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5")227 228 ctx.lineWidth = 1.5;229 ctx.lineWidth = -1;230 assert.strictEqual(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5")231 232 ctx.lineWidth = 1.5;233 ctx.lineWidth = Infinity;234 assert.strictEqual(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5")235 236 ctx.lineWidth = 1.5;237 ctx.lineWidth = -Infinity;238 assert.strictEqual(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5")239 240 ctx.lineWidth = 1.5;241 ctx.lineWidth = NaN;242 assert.strictEqual(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5")243 244 ctx.lineWidth = 1.5;245 ctx.lineWidth = 'string';246 assert.strictEqual(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5")247 248 ctx.lineWidth = 1.5;249 ctx.lineWidth = true;250 assert.strictEqual(ctx.lineWidth, 1, "ctx.lineWidth", "1")251 252 ctx.lineWidth = 1.5;253 ctx.lineWidth = false;254 assert.strictEqual(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5")255 });256 it("2d.line.cap.butt", function () {257 // lineCap 'butt' is rendered correctly258 const canvas = createCanvas(100, 50);259 const ctx = canvas.getContext("2d");260 const t = new Test();261 ctx.fillStyle = '#0f0';262 ctx.fillRect(0, 0, 100, 50);263 264 ctx.lineCap = 'butt';265 ctx.lineWidth = 20;266 267 ctx.fillStyle = '#f00';268 ctx.strokeStyle = '#0f0';269 ctx.fillRect(15, 15, 20, 20);270 ctx.beginPath();271 ctx.moveTo(25, 15);272 ctx.lineTo(25, 35);273 ctx.stroke();274 275 ctx.fillStyle = '#0f0';276 ctx.strokeStyle = '#f00';277 ctx.beginPath();278 ctx.moveTo(75, 15);279 ctx.lineTo(75, 35);280 ctx.stroke();281 ctx.fillRect(65, 15, 20, 20);282 283 _assertPixel(canvas, 25,14, 0,255,0,255);284 _assertPixel(canvas, 25,15, 0,255,0,255);285 _assertPixel(canvas, 25,16, 0,255,0,255);286 _assertPixel(canvas, 25,34, 0,255,0,255);287 _assertPixel(canvas, 25,35, 0,255,0,255);288 _assertPixel(canvas, 25,36, 0,255,0,255);289 290 _assertPixel(canvas, 75,14, 0,255,0,255);291 _assertPixel(canvas, 75,15, 0,255,0,255);292 _assertPixel(canvas, 75,16, 0,255,0,255);293 _assertPixel(canvas, 75,34, 0,255,0,255);294 _assertPixel(canvas, 75,35, 0,255,0,255);295 _assertPixel(canvas, 75,36, 0,255,0,255);296 });297 it("2d.line.cap.round", function () {298 // lineCap 'round' is rendered correctly299 const canvas = createCanvas(100, 50);300 const ctx = canvas.getContext("2d");301 const t = new Test();302 ctx.fillStyle = '#0f0';303 ctx.fillRect(0, 0, 100, 50);304 305 var tol = 1; // tolerance to avoid antialiasing artifacts306 307 ctx.lineCap = 'round';308 ctx.lineWidth = 20;309 310 311 ctx.fillStyle = '#f00';312 ctx.strokeStyle = '#0f0';313 314 ctx.beginPath();315 ctx.moveTo(35-tol, 15);316 ctx.arc(25, 15, 10-tol, 0, Math.PI, true);317 ctx.arc(25, 35, 10-tol, Math.PI, 0, true);318 ctx.fill();319 320 ctx.beginPath();321 ctx.moveTo(25, 15);322 ctx.lineTo(25, 35);323 ctx.stroke();324 325 326 ctx.fillStyle = '#0f0';327 ctx.strokeStyle = '#f00';328 329 ctx.beginPath();330 ctx.moveTo(75, 15);331 ctx.lineTo(75, 35);332 ctx.stroke();333 334 ctx.beginPath();335 ctx.moveTo(85+tol, 15);336 ctx.arc(75, 15, 10+tol, 0, Math.PI, true);337 ctx.arc(75, 35, 10+tol, Math.PI, 0, true);338 ctx.fill();339 340 _assertPixel(canvas, 17,6, 0,255,0,255);341 _assertPixel(canvas, 25,6, 0,255,0,255);342 _assertPixel(canvas, 32,6, 0,255,0,255);343 _assertPixel(canvas, 17,43, 0,255,0,255);344 _assertPixel(canvas, 25,43, 0,255,0,255);345 _assertPixel(canvas, 32,43, 0,255,0,255);346 347 _assertPixel(canvas, 67,6, 0,255,0,255);348 _assertPixel(canvas, 75,6, 0,255,0,255);349 _assertPixel(canvas, 82,6, 0,255,0,255);350 _assertPixel(canvas, 67,43, 0,255,0,255);351 _assertPixel(canvas, 75,43, 0,255,0,255);352 _assertPixel(canvas, 82,43, 0,255,0,255);353 });354 it("2d.line.cap.square", function () {355 // lineCap 'square' is rendered correctly356 const canvas = createCanvas(100, 50);357 const ctx = canvas.getContext("2d");358 const t = new Test();359 ctx.fillStyle = '#0f0';360 ctx.fillRect(0, 0, 100, 50);361 362 ctx.lineCap = 'square';363 ctx.lineWidth = 20;364 365 ctx.fillStyle = '#f00';366 ctx.strokeStyle = '#0f0';367 ctx.fillRect(15, 5, 20, 40);368 ctx.beginPath();369 ctx.moveTo(25, 15);370 ctx.lineTo(25, 35);371 ctx.stroke();372 373 ctx.fillStyle = '#0f0';374 ctx.strokeStyle = '#f00';375 ctx.beginPath();376 ctx.moveTo(75, 15);377 ctx.lineTo(75, 35);378 ctx.stroke();379 ctx.fillRect(65, 5, 20, 40);380 381 _assertPixel(canvas, 25,4, 0,255,0,255);382 _assertPixel(canvas, 25,5, 0,255,0,255);383 _assertPixel(canvas, 25,6, 0,255,0,255);384 _assertPixel(canvas, 25,44, 0,255,0,255);385 _assertPixel(canvas, 25,45, 0,255,0,255);386 _assertPixel(canvas, 25,46, 0,255,0,255);387 388 _assertPixel(canvas, 75,4, 0,255,0,255);389 _assertPixel(canvas, 75,5, 0,255,0,255);390 _assertPixel(canvas, 75,6, 0,255,0,255);391 _assertPixel(canvas, 75,44, 0,255,0,255);392 _assertPixel(canvas, 75,45, 0,255,0,255);393 _assertPixel(canvas, 75,46, 0,255,0,255);394 });395 it("2d.line.cap.open", function () {396 // Line caps are drawn at the corners of an unclosed rectangle397 const canvas = createCanvas(100, 50);398 const ctx = canvas.getContext("2d");399 const t = new Test();400 ctx.fillStyle = '#f00';401 ctx.strokeStyle = '#0f0';402 ctx.fillRect(0, 0, 100, 50);403 404 ctx.lineJoin = 'bevel';405 ctx.lineCap = 'square';406 ctx.lineWidth = 400;407 408 ctx.beginPath();409 ctx.moveTo(200, 200);410 ctx.lineTo(200, 1000);411 ctx.lineTo(1000, 1000);412 ctx.lineTo(1000, 200);413 ctx.lineTo(200, 200);414 ctx.stroke();415 416 _assertPixel(canvas, 1,1, 0,255,0,255);417 _assertPixel(canvas, 48,1, 0,255,0,255);418 _assertPixel(canvas, 48,48, 0,255,0,255);419 _assertPixel(canvas, 1,48, 0,255,0,255);420 });421 it("2d.line.cap.closed", function () {422 // Line caps are not drawn at the corners of an unclosed rectangle423 const canvas = createCanvas(100, 50);424 const ctx = canvas.getContext("2d");425 const t = new Test();426 ctx.fillStyle = '#0f0';427 ctx.strokeStyle = '#f00';428 ctx.fillRect(0, 0, 100, 50);429 430 ctx.lineJoin = 'bevel';431 ctx.lineCap = 'square';432 ctx.lineWidth = 400;433 434 ctx.beginPath();435 ctx.moveTo(200, 200);436 ctx.lineTo(200, 1000);437 ctx.lineTo(1000, 1000);438 ctx.lineTo(1000, 200);439 ctx.closePath();440 ctx.stroke();441 442 _assertPixel(canvas, 1,1, 0,255,0,255);443 _assertPixel(canvas, 48,1, 0,255,0,255);444 _assertPixel(canvas, 48,48, 0,255,0,255);445 _assertPixel(canvas, 1,48, 0,255,0,255);446 });447 it("2d.line.cap.valid", function () {448 // Setting lineCap to valid values works449 const canvas = createCanvas(100, 50);450 const ctx = canvas.getContext("2d");451 const t = new Test();452 ctx.lineCap = 'butt'453 assert.strictEqual(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'")454 455 ctx.lineCap = 'round';456 assert.strictEqual(ctx.lineCap, 'round', "ctx.lineCap", "'round'")457 458 ctx.lineCap = 'square';459 assert.strictEqual(ctx.lineCap, 'square', "ctx.lineCap", "'square'")460 });461 it("2d.line.cap.invalid", function () {462 // Setting lineCap to invalid values is ignored463 const canvas = createCanvas(100, 50);464 const ctx = canvas.getContext("2d");465 const t = new Test();466 ctx.lineCap = 'butt'467 assert.strictEqual(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'")468 469 ctx.lineCap = 'butt';470 ctx.lineCap = 'invalid';471 assert.strictEqual(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'")472 473 ctx.lineCap = 'butt';474 ctx.lineCap = 'ROUND';475 assert.strictEqual(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'")476 477 ctx.lineCap = 'butt';478 ctx.lineCap = 'round\0';479 assert.strictEqual(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'")480 481 ctx.lineCap = 'butt';482 ctx.lineCap = 'round ';483 assert.strictEqual(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'")484 485 ctx.lineCap = 'butt';486 ctx.lineCap = "";487 assert.strictEqual(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'")488 489 ctx.lineCap = 'butt';490 ctx.lineCap = 'bevel';491 assert.strictEqual(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'")492 });493 it("2d.line.join.bevel", function () {494 // lineJoin 'bevel' is rendered correctly495 const canvas = createCanvas(100, 50);496 const ctx = canvas.getContext("2d");497 const t = new Test();498 ctx.fillStyle = '#0f0';499 ctx.fillRect(0, 0, 100, 50);500 501 var tol = 1; // tolerance to avoid antialiasing artifacts502 503 ctx.lineJoin = 'bevel';504 ctx.lineWidth = 20;505 506 ctx.fillStyle = '#f00';507 ctx.strokeStyle = '#0f0';508 509 ctx.fillRect(10, 10, 20, 20);510 ctx.fillRect(20, 20, 20, 20);511 ctx.beginPath();512 ctx.moveTo(30, 20);513 ctx.lineTo(40-tol, 20);514 ctx.lineTo(30, 10+tol);515 ctx.fill();516 517 ctx.beginPath();518 ctx.moveTo(10, 20);519 ctx.lineTo(30, 20);520 ctx.lineTo(30, 40);521 ctx.stroke();522 523 524 ctx.fillStyle = '#0f0';525 ctx.strokeStyle = '#f00';526 527 ctx.beginPath();528 ctx.moveTo(60, 20);529 ctx.lineTo(80, 20);530 ctx.lineTo(80, 40);531 ctx.stroke();532 533 ctx.fillRect(60, 10, 20, 20);534 ctx.fillRect(70, 20, 20, 20);535 ctx.beginPath();536 ctx.moveTo(80, 20);537 ctx.lineTo(90+tol, 20);538 ctx.lineTo(80, 10-tol);539 ctx.fill();540 541 _assertPixel(canvas, 34,16, 0,255,0,255);542 _assertPixel(canvas, 34,15, 0,255,0,255);543 _assertPixel(canvas, 35,15, 0,255,0,255);544 _assertPixel(canvas, 36,15, 0,255,0,255);545 _assertPixel(canvas, 36,14, 0,255,0,255);546 547 _assertPixel(canvas, 84,16, 0,255,0,255);548 _assertPixel(canvas, 84,15, 0,255,0,255);549 _assertPixel(canvas, 85,15, 0,255,0,255);550 _assertPixel(canvas, 86,15, 0,255,0,255);551 _assertPixel(canvas, 86,14, 0,255,0,255);552 });553 it("2d.line.join.round", function () {554 // lineJoin 'round' is rendered correctly555 const canvas = createCanvas(100, 50);556 const ctx = canvas.getContext("2d");557 const t = new Test();558 ctx.fillStyle = '#0f0';559 ctx.fillRect(0, 0, 100, 50);560 561 var tol = 1; // tolerance to avoid antialiasing artifacts562 563 ctx.lineJoin = 'round';564 ctx.lineWidth = 20;565 566 ctx.fillStyle = '#f00';567 ctx.strokeStyle = '#0f0';568 569 ctx.fillRect(10, 10, 20, 20);570 ctx.fillRect(20, 20, 20, 20);571 ctx.beginPath();572 ctx.moveTo(30, 20);573 ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true);574 ctx.fill();575 576 ctx.beginPath();577 ctx.moveTo(10, 20);578 ctx.lineTo(30, 20);579 ctx.lineTo(30, 40);580 ctx.stroke();581 582 583 ctx.fillStyle = '#0f0';584 ctx.strokeStyle = '#f00';585 586 ctx.beginPath();587 ctx.moveTo(60, 20);588 ctx.lineTo(80, 20);589 ctx.lineTo(80, 40);590 ctx.stroke();591 592 ctx.fillRect(60, 10, 20, 20);593 ctx.fillRect(70, 20, 20, 20);594 ctx.beginPath();595 ctx.moveTo(80, 20);596 ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true);597 ctx.fill();598 599 _assertPixel(canvas, 36,14, 0,255,0,255);600 _assertPixel(canvas, 36,13, 0,255,0,255);601 _assertPixel(canvas, 37,13, 0,255,0,255);602 _assertPixel(canvas, 38,13, 0,255,0,255);603 _assertPixel(canvas, 38,12, 0,255,0,255);604 605 _assertPixel(canvas, 86,14, 0,255,0,255);606 _assertPixel(canvas, 86,13, 0,255,0,255);607 _assertPixel(canvas, 87,13, 0,255,0,255);608 _assertPixel(canvas, 88,13, 0,255,0,255);609 _assertPixel(canvas, 88,12, 0,255,0,255);610 });611 it("2d.line.join.miter", function () {612 // lineJoin 'miter' is rendered correctly613 const canvas = createCanvas(100, 50);614 const ctx = canvas.getContext("2d");615 const t = new Test();616 ctx.fillStyle = '#0f0';617 ctx.fillRect(0, 0, 100, 50);618 619 ctx.lineJoin = 'miter';620 ctx.lineWidth = 20;621 622 ctx.fillStyle = '#f00';623 ctx.strokeStyle = '#0f0';624 625 ctx.fillStyle = '#f00';626 ctx.strokeStyle = '#0f0';627 628 ctx.fillRect(10, 10, 30, 20);629 ctx.fillRect(20, 10, 20, 30);630 631 ctx.beginPath();632 ctx.moveTo(10, 20);633 ctx.lineTo(30, 20);634 ctx.lineTo(30, 40);635 ctx.stroke();636 637 638 ctx.fillStyle = '#0f0';639 ctx.strokeStyle = '#f00';640 641 ctx.beginPath();642 ctx.moveTo(60, 20);643 ctx.lineTo(80, 20);644 ctx.lineTo(80, 40);645 ctx.stroke();646 647 ctx.fillRect(60, 10, 30, 20);648 ctx.fillRect(70, 10, 20, 30);649 650 _assertPixel(canvas, 38,12, 0,255,0,255);651 _assertPixel(canvas, 39,11, 0,255,0,255);652 _assertPixel(canvas, 40,10, 0,255,0,255);653 _assertPixel(canvas, 41,9, 0,255,0,255);654 _assertPixel(canvas, 42,8, 0,255,0,255);655 656 _assertPixel(canvas, 88,12, 0,255,0,255);657 _assertPixel(canvas, 89,11, 0,255,0,255);658 _assertPixel(canvas, 90,10, 0,255,0,255);659 _assertPixel(canvas, 91,9, 0,255,0,255);660 _assertPixel(canvas, 92,8, 0,255,0,255);661 });662 it("2d.line.join.open", function () {663 // Line joins are not drawn at the corner of an unclosed rectangle664 const canvas = createCanvas(100, 50);665 const ctx = canvas.getContext("2d");666 const t = new Test();667 ctx.fillStyle = '#0f0';668 ctx.strokeStyle = '#f00';669 ctx.fillRect(0, 0, 100, 50);670 671 ctx.lineJoin = 'miter';672 ctx.lineWidth = 200;673 674 ctx.beginPath();675 ctx.moveTo(100, 50);676 ctx.lineTo(100, 1000);677 ctx.lineTo(1000, 1000);678 ctx.lineTo(1000, 50);679 ctx.lineTo(100, 50);680 ctx.stroke();681 682 _assertPixel(canvas, 1,1, 0,255,0,255);683 _assertPixel(canvas, 48,1, 0,255,0,255);684 _assertPixel(canvas, 48,48, 0,255,0,255);685 _assertPixel(canvas, 1,48, 0,255,0,255);686 });687 it("2d.line.join.closed", function () {688 // Line joins are drawn at the corner of a closed rectangle689 const canvas = createCanvas(100, 50);690 const ctx = canvas.getContext("2d");691 const t = new Test();692 ctx.fillStyle = '#f00';693 ctx.strokeStyle = '#0f0';694 ctx.fillRect(0, 0, 100, 50);695 696 ctx.lineJoin = 'miter';697 ctx.lineWidth = 200;698 699 ctx.beginPath();700 ctx.moveTo(100, 50);701 ctx.lineTo(100, 1000);702 ctx.lineTo(1000, 1000);703 ctx.lineTo(1000, 50);704 ctx.closePath();705 ctx.stroke();706 707 _assertPixel(canvas, 1,1, 0,255,0,255);708 _assertPixel(canvas, 48,1, 0,255,0,255);709 _assertPixel(canvas, 48,48, 0,255,0,255);710 _assertPixel(canvas, 1,48, 0,255,0,255);711 });712 it("2d.line.join.parallel", function () {713 // Line joins are drawn at 180-degree joins714 const canvas = createCanvas(100, 50);715 const ctx = canvas.getContext("2d");716 const t = new Test();717 ctx.fillStyle = '#f00';718 ctx.fillRect(0, 0, 100, 50);719 720 ctx.strokeStyle = '#0f0';721 ctx.lineWidth = 300;722 ctx.lineJoin = 'round';723 ctx.beginPath();724 ctx.moveTo(-100, 25);725 ctx.lineTo(0, 25);726 ctx.lineTo(-100, 25);727 ctx.stroke();728 729 _assertPixel(canvas, 1,1, 0,255,0,255);730 _assertPixel(canvas, 48,1, 0,255,0,255);731 _assertPixel(canvas, 48,48, 0,255,0,255);732 _assertPixel(canvas, 1,48, 0,255,0,255);733 });734 it("2d.line.join.valid", function () {735 // Setting lineJoin to valid values works736 const canvas = createCanvas(100, 50);737 const ctx = canvas.getContext("2d");738 const t = new Test();739 ctx.lineJoin = 'bevel'740 assert.strictEqual(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'")741 742 ctx.lineJoin = 'round';743 assert.strictEqual(ctx.lineJoin, 'round', "ctx.lineJoin", "'round'")744 745 ctx.lineJoin = 'miter';746 assert.strictEqual(ctx.lineJoin, 'miter', "ctx.lineJoin", "'miter'")747 });748 it("2d.line.join.invalid", function () {749 // Setting lineJoin to invalid values is ignored750 const canvas = createCanvas(100, 50);751 const ctx = canvas.getContext("2d");752 const t = new Test();753 ctx.lineJoin = 'bevel'754 assert.strictEqual(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'")755 756 ctx.lineJoin = 'bevel';757 ctx.lineJoin = 'invalid';758 assert.strictEqual(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'")759 760 ctx.lineJoin = 'bevel';761 ctx.lineJoin = 'ROUND';762 assert.strictEqual(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'")763 764 ctx.lineJoin = 'bevel';765 ctx.lineJoin = 'round\0';766 assert.strictEqual(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'")767 768 ctx.lineJoin = 'bevel';769 ctx.lineJoin = 'round ';770 assert.strictEqual(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'")771 772 ctx.lineJoin = 'bevel';773 ctx.lineJoin = "";774 assert.strictEqual(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'")775 776 ctx.lineJoin = 'bevel';777 ctx.lineJoin = 'butt';778 assert.strictEqual(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'")779 });780 it("2d.line.miter.exceeded", function () {781 // Miter joins are not drawn when the miter limit is exceeded782 const canvas = createCanvas(100, 50);783 const ctx = canvas.getContext("2d");784 const t = new Test();785 ctx.fillStyle = '#0f0';786 ctx.fillRect(0, 0, 100, 50);787 788 ctx.lineWidth = 400;789 ctx.lineJoin = 'miter';790 791 ctx.strokeStyle = '#f00';792 ctx.miterLimit = 1.414;793 ctx.beginPath();794 ctx.moveTo(200, 1000);795 ctx.lineTo(200, 200);796 ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case797 ctx.stroke();798 799 _assertPixel(canvas, 1,1, 0,255,0,255);800 _assertPixel(canvas, 48,1, 0,255,0,255);801 _assertPixel(canvas, 48,48, 0,255,0,255);802 _assertPixel(canvas, 1,48, 0,255,0,255);803 });804 it("2d.line.miter.acute", function () {805 // Miter joins are drawn correctly with acute angles806 const canvas = createCanvas(100, 50);807 const ctx = canvas.getContext("2d");808 const t = new Test();809 ctx.fillStyle = '#f00';810 ctx.fillRect(0, 0, 100, 50);811 812 ctx.lineWidth = 200;813 ctx.lineJoin = 'miter';814 815 ctx.strokeStyle = '#0f0';816 ctx.miterLimit = 2.614;817 ctx.beginPath();818 ctx.moveTo(100, 1000);819 ctx.lineTo(100, 100);820 ctx.lineTo(1000, 1000);821 ctx.stroke();822 823 ctx.strokeStyle = '#f00';824 ctx.miterLimit = 2.613;825 ctx.beginPath();826 ctx.moveTo(100, 1000);827 ctx.lineTo(100, 100);828 ctx.lineTo(1000, 1000);829 ctx.stroke();830 831 _assertPixel(canvas, 1,1, 0,255,0,255);832 _assertPixel(canvas, 48,1, 0,255,0,255);833 _assertPixel(canvas, 48,48, 0,255,0,255);834 _assertPixel(canvas, 1,48, 0,255,0,255);835 });836 it("2d.line.miter.obtuse", function () {837 // Miter joins are drawn correctly with obtuse angles838 const canvas = createCanvas(100, 50);839 const ctx = canvas.getContext("2d");840 const t = new Test();841 ctx.fillStyle = '#f00';842 ctx.fillRect(0, 0, 100, 50);843 844 ctx.lineWidth = 1600;845 ctx.lineJoin = 'miter';846 847 ctx.strokeStyle = '#0f0';848 ctx.miterLimit = 1.083;849 ctx.beginPath();850 ctx.moveTo(800, 10000);851 ctx.lineTo(800, 300);852 ctx.lineTo(10000, -8900);853 ctx.stroke();854 855 ctx.strokeStyle = '#f00';856 ctx.miterLimit = 1.082;857 ctx.beginPath();858 ctx.moveTo(800, 10000);859 ctx.lineTo(800, 300);860 ctx.lineTo(10000, -8900);861 ctx.stroke();862 863 _assertPixel(canvas, 1,1, 0,255,0,255);864 _assertPixel(canvas, 48,1, 0,255,0,255);865 _assertPixel(canvas, 48,48, 0,255,0,255);866 _assertPixel(canvas, 1,48, 0,255,0,255);867 });868 it("2d.line.miter.rightangle", function () {869 // Miter joins are not drawn when the miter limit is exceeded, on exact right angles870 const canvas = createCanvas(100, 50);871 const ctx = canvas.getContext("2d");872 const t = new Test();873 ctx.fillStyle = '#0f0';874 ctx.fillRect(0, 0, 100, 50);875 876 ctx.lineWidth = 400;877 ctx.lineJoin = 'miter';878 879 ctx.strokeStyle = '#f00';880 ctx.miterLimit = 1.414;881 ctx.beginPath();882 ctx.moveTo(200, 1000);883 ctx.lineTo(200, 200);884 ctx.lineTo(1000, 200);885 ctx.stroke();886 887 _assertPixel(canvas, 1,1, 0,255,0,255);888 _assertPixel(canvas, 48,1, 0,255,0,255);889 _assertPixel(canvas, 48,48, 0,255,0,255);890 _assertPixel(canvas, 1,48, 0,255,0,255);891 });892 it("2d.line.miter.lineedge", function () {893 // Miter joins are not drawn when the miter limit is exceeded at the corners of a zero-height rectangle894 const canvas = createCanvas(100, 50);895 const ctx = canvas.getContext("2d");896 const t = new Test();897 ctx.fillStyle = '#0f0';898 ctx.fillRect(0, 0, 100, 50);899 900 ctx.lineWidth = 200;901 ctx.lineJoin = 'miter';902 903 ctx.strokeStyle = '#f00';904 ctx.miterLimit = 1.414;905 ctx.beginPath();906 ctx.strokeRect(100, 25, 200, 0);907 908 _assertPixel(canvas, 1,1, 0,255,0,255);909 _assertPixel(canvas, 48,1, 0,255,0,255);910 _assertPixel(canvas, 48,48, 0,255,0,255);911 _assertPixel(canvas, 1,48, 0,255,0,255);912 });913 it("2d.line.miter.within", function () {914 // Miter joins are drawn when the miter limit is not quite exceeded915 const canvas = createCanvas(100, 50);916 const ctx = canvas.getContext("2d");917 const t = new Test();918 ctx.fillStyle = '#f00';919 ctx.fillRect(0, 0, 100, 50);920 921 ctx.lineWidth = 400;922 ctx.lineJoin = 'miter';923 924 ctx.strokeStyle = '#0f0';925 ctx.miterLimit = 1.416;926 ctx.beginPath();927 ctx.moveTo(200, 1000);928 ctx.lineTo(200, 200);929 ctx.lineTo(1000, 201);930 ctx.stroke();931 932 _assertPixel(canvas, 1,1, 0,255,0,255);933 _assertPixel(canvas, 48,1, 0,255,0,255);934 _assertPixel(canvas, 48,48, 0,255,0,255);935 _assertPixel(canvas, 1,48, 0,255,0,255);936 });937 it("2d.line.miter.valid", function () {938 // Setting miterLimit to valid values works939 const canvas = createCanvas(100, 50);940 const ctx = canvas.getContext("2d");941 const t = new Test();942 ctx.miterLimit = 1.5;943 assert.strictEqual(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5")944 945 ctx.miterLimit = "1e1";946 assert.strictEqual(ctx.miterLimit, 10, "ctx.miterLimit", "10")947 948 ctx.miterLimit = 1/1024;949 assert.strictEqual(ctx.miterLimit, 1/1024, "ctx.miterLimit", "1/1024")950 951 ctx.miterLimit = 1000;952 assert.strictEqual(ctx.miterLimit, 1000, "ctx.miterLimit", "1000")953 });954 it("2d.line.miter.invalid", function () {955 // Setting miterLimit to invalid values is ignored956 const canvas = createCanvas(100, 50);957 const ctx = canvas.getContext("2d");958 const t = new Test();959 ctx.miterLimit = 1.5;960 assert.strictEqual(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5")961 962 ctx.miterLimit = 1.5;963 ctx.miterLimit = 0;964 assert.strictEqual(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5")965 966 ctx.miterLimit = 1.5;967 ctx.miterLimit = -1;968 assert.strictEqual(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5")969 970 ctx.miterLimit = 1.5;971 ctx.miterLimit = Infinity;972 assert.strictEqual(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5")973 974 ctx.miterLimit = 1.5;975 ctx.miterLimit = -Infinity;976 assert.strictEqual(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5")977 978 ctx.miterLimit = 1.5;979 ctx.miterLimit = NaN;980 assert.strictEqual(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5")981 982 ctx.miterLimit = 1.5;983 ctx.miterLimit = 'string';984 assert.strictEqual(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5")985 986 ctx.miterLimit = 1.5;987 ctx.miterLimit = true;988 assert.strictEqual(ctx.miterLimit, 1, "ctx.miterLimit", "1")989 990 ctx.miterLimit = 1.5;991 ctx.miterLimit = false;992 assert.strictEqual(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5")993 });994 it("2d.line.cross", function () {995 const canvas = createCanvas(100, 50);996 const ctx = canvas.getContext("2d");997 const t = new Test();998 ctx.fillStyle = '#0f0';999 ctx.fillRect(0, 0, 100, 50);1000 1001 ctx.lineWidth = 200;1002 ctx.lineJoin = 'bevel';1003 1004 ctx.strokeStyle = '#f00';1005 ctx.beginPath();1006 ctx.moveTo(110, 50);1007 ctx.lineTo(110, 60);1008 ctx.lineTo(100, 60);1009 ctx.stroke();1010 1011 _assertPixel(canvas, 1,1, 0,255,0,255);1012 _assertPixel(canvas, 48,1, 0,255,0,255);1013 _assertPixel(canvas, 48,48, 0,255,0,255);1014 _assertPixel(canvas, 1,48, 0,255,0,255);1015 });1016 it("2d.line.union", function () {1017 const canvas = createCanvas(100, 50);1018 const ctx = canvas.getContext("2d");1019 const t = new Test();1020 ctx.fillStyle = '#f00';1021 ctx.fillRect(0, 0, 100, 50);1022 1023 ctx.lineWidth = 100;1024 ctx.lineCap = 'round';1025 1026 ctx.strokeStyle = '#0f0';1027 ctx.beginPath();1028 ctx.moveTo(0, 24);1029 ctx.lineTo(100, 25);1030 ctx.lineTo(0, 26);1031 ctx.closePath();1032 ctx.stroke();1033 1034 _assertPixel(canvas, 1,1, 0,255,0,255);1035 _assertPixel(canvas, 25,1, 0,255,0,255);1036 _assertPixel(canvas, 48,1, 0,255,0,255);1037 _assertPixel(canvas, 1,48, 0,255,0,255);1038 _assertPixel(canvas, 25,1, 0,255,0,255);1039 _assertPixel(canvas, 48,48, 0,255,0,255);1040 });1041 it("2d.line.invalid.strokestyle", function () {1042 // Verify correct behavior of canvas on an invalid strokeStyle()1043 const canvas = createCanvas(100, 50);1044 const ctx = canvas.getContext("2d");1045 const t = new Test();1046 ctx.strokeStyle = 'rgb(0, 255, 0)';1047 ctx.strokeStyle = 'nonsense';1048 ctx.lineWidth = 200;1049 ctx.moveTo(0,100);1050 ctx.lineTo(200,100);1051 ctx.stroke();1052 var imageData = ctx.getImageData(0, 0, 200, 200);1053 var imgdata = imageData.data;...
CanvasRenderingContext2D.test.js
Source:CanvasRenderingContext2D.test.js
...9 });10 it('fillRect works', function() {11 ctx.fillStyle = '#0f0';12 ctx.fillRect(0, 0, 100, 50);13 _assertPixel(gl, 50, 25, 0, 255, 0, 255);14 });15 it('fillRect red-green gradient', function() {16 var options = { width: 150, height: 150, fileName: this.test.fullTitle() };17 ({ gl, ctx } = _initContext(options));18 for (var i = 0; i < 6; i++) {19 for (var j = 0; j < 6; j++) {20 ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ',' +21 Math.floor(255 - 42.5 * j) + ',0)';22 ctx.fillRect(j * 25, i * 25, 25, 25);23 }24 }25 _assertOutput(gl, options);26 })27});28describe('2d.strokeRect', function() {29 var gl, ctx;30 beforeEach(function() {31 ({ gl, ctx } = _initContext());32 });33 it('strokeRect works', function() {34 ctx.strokeStyle = '#0f0';35 ctx.lineWidth = 50;36 ctx.strokeRect(25, 24, 50, 2);37 _assertPixel(gl, 50, 25, 0, 255, 0, 255);38 });39});40describe('2d.clearRect', function() {41 var gl, ctx;42 beforeEach(function() {43 ({ gl, ctx } = _initContext());44 });45 it('clearRect basic', function() {46 ctx.fillStyle = '#f00';47 ctx.fillRect(0, 0, 100, 50);48 ctx.clearRect(0, 0, 100, 50);49 _assertPixel(gl, 50, 25, 0, 0, 0, 0);50 });51});52describe('2d.path', function() {53 var gl, ctx;54 beforeEach(function() {55 ({ gl, ctx } = _initContext());56 });57 it('2d.path.rect.basic', function() {58 ctx.fillStyle = '#f00';59 ctx.fillRect(0, 0, 100, 50);60 ctx.fillStyle = '#0f0';61 ctx.rect(0, 0, 100, 50);62 ctx.fill();63 _assertPixel(gl, 50, 25, 0, 255, 0, 255)64 });65 // EK: The closePath() method, when invoked, must do nothing if the object's path has no subpaths. 66 // Basically a NOP.67 it('2d.path.initial', function() {68 ctx.fillStyle = '#0f0';69 ctx.fillRect(0, 0, 100, 50);70 ctx.closePath();71 ctx.fillStyle = '#f00';72 ctx.fill();73 _assertPixel(gl, 50, 25, 0, 255, 0, 255);74 });75 it('2d.path.beginPath', function() {76 ctx.fillStyle = '#0f0';77 ctx.fillRect(0, 0, 100, 50);78 ctx.rect(0, 0, 100, 50);79 ctx.beginPath();80 ctx.fillStyle = '#f00';81 ctx.fill();82 _assertPixel(gl, 50, 25, 0, 255, 0, 255);83 });84 it('2d.path.moveTo.basic', function() {85 ctx.fillStyle = '#f00';86 ctx.fillRect(0, 0, 100, 50);87 ctx.rect(0, 0, 10, 50);88 ctx.moveTo(100, 0);89 ctx.lineTo(10, 0);90 ctx.lineTo(10, 50);91 ctx.lineTo(100, 50);92 ctx.fillStyle = '#0f0';93 ctx.fill();94 _assertPixel(gl, 90, 25, 0, 255, 0, 255);95 });96 it('2d.path.moveTo.newsubpath', function() {97 ctx.fillStyle = '#0f0';98 ctx.fillRect(0, 0, 100, 50);99 ctx.beginPath();100 ctx.moveTo(0, 0);101 ctx.moveTo(100, 0);102 ctx.moveTo(100, 50);103 ctx.moveTo(0, 50);104 ctx.fillStyle = '#f00';105 ctx.fill();106 _assertPixel(gl, 50, 25, 0, 255, 0, 255);107 });108 // arc() with an empty path does not draw a straight line to the start point109 it('2d.path.arc.empty', function() {110 ctx.fillStyle = '#0f0';111 ctx.fillRect(0, 0, 100, 50);112 ctx.lineWidth = 50;113 ctx.strokeStyle = '#f00';114 ctx.beginPath();115 ctx.arc(200, 25, 5, 0, 2 * Math.PI, true);116 ctx.stroke();117 _assertPixel(gl, 50, 25, 0, 255, 0, 255);118 })119 // arc() with a non-empty path does draw a straight line to the start point120 it('2d.path.arc.nonempty', function() {121 ctx.fillStyle = '#f00';122 ctx.fillRect(0, 0, 100, 50);123 ctx.lineWidth = 50;124 ctx.strokeStyle = '#0f0';125 ctx.beginPath();126 ctx.moveTo(0, 25);127 ctx.arc(200, 25, 5, 0, 2 * Math.PI, true);128 ctx.stroke();129 _assertPixel(gl, 50, 25, 0, 255, 0, 255);130 })131 // arc() adds the end point of the arc to the subpath132 it('2d.path.arc.end', function() {133 ctx.fillStyle = '#f00';134 ctx.fillRect(0, 0, 100, 50);135 ctx.lineWidth = 50;136 ctx.strokeStyle = '#0f0';137 ctx.beginPath();138 ctx.moveTo(-100, 0);139 ctx.arc(-100, 0, 25, -Math.PI / 2, Math.PI / 2, true);140 ctx.lineTo(100, 25);141 ctx.stroke();142 _assertPixel(gl, 50, 25, 0, 255, 0, 255);143 });144 // arc() with missing last argument defaults to clockwise145 it('2d.path.arc.default', function() {146 ctx.fillStyle = '#0f0';147 ctx.fillRect(0, 0, 100, 50);148 ctx.fillStyle = '#f00';149 ctx.beginPath();150 ctx.moveTo(100, 0);151 ctx.arc(100, 0, 150, -Math.PI, Math.PI / 2);152 ctx.fill();153 _assertPixel(gl, 50, 25, 0, 255, 0, 255);154 });155 // arc() draws pi/2 .. -pi anticlockwise correctly156 it('2d.path.arc.angle.1', function() {157 ctx.fillStyle = '#0f0';158 ctx.fillRect(0, 0, 100, 50);159 ctx.fillStyle = '#f00';160 ctx.beginPath();161 ctx.moveTo(100, 0);162 ctx.arc(100, 0, 150, Math.PI / 2, -Math.PI, true);163 ctx.fill();164 _assertPixel(gl, 50, 25, 0, 255, 0, 255);165 });166 // arc() draws -3pi/2 .. -pi anticlockwise correctly167 it('2d.path.arc.angle.2', function() {168 ctx.fillStyle = '#0f0';169 ctx.fillRect(0, 0, 100, 50);170 ctx.fillStyle = '#f00';171 ctx.beginPath();172 ctx.moveTo(100, 0);173 ctx.arc(100, 0, 150, -3 * Math.PI / 2, -Math.PI, true);174 ctx.fill();175 _assertPixel(gl, 50, 25, 0, 255, 0, 255);176 });177 // arc() wraps angles mod 2pi when anticlockwise and end > start+2pi178 it('2d.path.arc.angle.3', function() {179 ctx.fillStyle = '#0f0';180 ctx.fillRect(0, 0, 100, 50);181 ctx.fillStyle = '#f00';182 ctx.beginPath();183 ctx.moveTo(100, 0);184 ctx.arc(100, 0, 150, (512 + 1 / 2) * Math.PI, (1024 - 1) * Math.PI, true);185 ctx.fill();186 _assertPixel(gl, 50, 25, 0, 255, 0, 255);187 });188 // arc() draws a full circle when clockwise and end > start+2pi189 it('2d.path.arc.angle.4', function() {190 ctx.fillStyle = '#f00';191 ctx.fillRect(0, 0, 100, 50);192 ctx.fillStyle = '#0f0';193 ctx.beginPath();194 ctx.moveTo(50, 25);195 ctx.arc(50, 25, 60, (512 + 1 / 2) * Math.PI, (1024 - 1) * Math.PI, false);196 ctx.fill();197 _assertPixel(gl, 1, 1, 0, 255, 0, 255);198 _assertPixel(gl, 98, 1, 0, 255, 0, 255);199 _assertPixel(gl, 1, 48, 0, 255, 0, 255);200 _assertPixel(gl, 98, 48, 0, 255, 0, 255);201 });202 // arc() wraps angles mod 2pi when clockwise and start > end+2pi203 it('2d.path.arc.angle.5', function() {204 ctx.fillStyle = '#0f0';205 ctx.fillRect(0, 0, 100, 50);206 ctx.fillStyle = '#f00';207 ctx.beginPath();208 ctx.moveTo(100, 0);209 ctx.arc(100, 0, 150, (1024 - 1) * Math.PI, (512 + 1 / 2) * Math.PI, false);210 ctx.fill();211 _assertPixel(gl, 50, 25, 0, 255, 0, 255);212 });213 // arc() draws a full circle when anticlockwise and start > end+2pi214 it('2d.path.arc.angle.6', function() {215 ctx.fillStyle = '#f00';216 ctx.fillRect(0, 0, 100, 50);217 ctx.fillStyle = '#0f0';218 ctx.beginPath();219 ctx.moveTo(50, 25);220 ctx.arc(50, 25, 60, (1024 - 1) * Math.PI, (512 + 1 / 2) * Math.PI, true);221 ctx.fill();222 _assertPixel(gl, 1, 1, 0, 255, 0, 255);223 _assertPixel(gl, 98, 1, 0, 255, 0, 255);224 _assertPixel(gl, 1, 48, 0, 255, 0, 255);225 _assertPixel(gl, 98, 48, 0, 255, 0, 255);226 });227 // arc() draws nothing when startAngle = endAngle and anticlockwise228 it('2d.path.arc.zero.1', function() {229 ctx.fillStyle = '#0f0';230 ctx.fillRect(0, 0, 100, 50);231 ctx.strokeStyle = '#f00';232 ctx.lineWidth = 100;233 ctx.beginPath();234 ctx.arc(50, 25, 50, 0, 0, true);235 ctx.stroke();236 _assertPixel(gl, 50, 20, 0, 255, 0, 255);237 });238 // arc() draws nothing when startAngle = endAngle and clockwise239 it('2d.path.arc.zero.2', function() {240 ctx.fillStyle = '#0f0';241 ctx.fillRect(0, 0, 100, 50);242 ctx.strokeStyle = '#f00';243 ctx.lineWidth = 100;244 ctx.beginPath();245 ctx.arc(50, 25, 50, 0, 0, false);246 ctx.stroke();247 _assertPixel(gl, 50, 20, 0, 255, 0, 255);248 });249 // arc() draws nothing when end = start + 2pi-e and anticlockwise250 it('2d.path.arc.twopie.1', function() {251 ctx.fillStyle = '#0f0';252 ctx.fillRect(0, 0, 100, 50);253 ctx.strokeStyle = '#f00';254 ctx.lineWidth = 100;255 ctx.beginPath();256 ctx.arc(50, 25, 50, 0, 2 * Math.PI - 1e-4, true);257 ctx.stroke();258 _assertPixel(gl, 50, 20, 0, 255, 0, 255);259 });260 // arc() draws a full circle when end = start + 2pi-e and clockwise261 it('2d.path.arc.twopie.2', function() {262 ctx.fillStyle = '#f00';263 ctx.fillRect(0, 0, 100, 50);264 ctx.strokeStyle = '#0f0';265 ctx.lineWidth = 100;266 ctx.beginPath();267 ctx.arc(50, 25, 50, 0, 2 * Math.PI - 1e-4, false);268 ctx.stroke();269 _assertPixel(gl, 50, 20, 0, 255, 0, 255);270 });271 // arc() draws a full circle when end = start + 2pi+e and anticlockwise272 it('2d.path.arc.twopie.3', function() {273 ctx.fillStyle = '#f00';274 ctx.fillRect(0, 0, 100, 50);275 ctx.strokeStyle = '#0f0';276 ctx.lineWidth = 100;277 ctx.beginPath();278 ctx.arc(50, 25, 50, 0, 2 * Math.PI + 1e-4, true);279 ctx.stroke();280 _assertPixel(gl, 50, 20, 0, 255, 0, 255);281 });282 // arc() draws nothing when end = start + 2pi+e and clockwise283 it('2d.path.arc.twopie.4', function() {284 ctx.fillStyle = '#f00';285 ctx.fillRect(0, 0, 100, 50);286 ctx.strokeStyle = '#0f0';287 ctx.lineWidth = 100;288 ctx.beginPath();289 ctx.arc(50, 25, 50, 0, 2 * Math.PI + 1e-4, false);290 ctx.stroke();291 _assertPixel(gl, 50, 20, 0, 255, 0, 255);292 });293 // arc() from 0 to pi does not draw anything in the wrong half294 it('2d.path.arc.shape.1', function() {295 ctx.fillStyle = '#0f0';296 ctx.fillRect(0, 0, 100, 50);297 ctx.lineWidth = 50;298 ctx.strokeStyle = '#f00';299 ctx.beginPath();300 ctx.arc(50, 50, 50, 0, Math.PI, false);301 ctx.stroke();302 _assertPixel(gl, 50, 25, 0, 255, 0, 255);303 _assertPixel(gl, 1, 1, 0, 255, 0, 255);304 _assertPixel(gl, 98, 1, 0, 255, 0, 255);305 _assertPixel(gl, 1, 48, 0, 255, 0, 255);306 _assertPixel(gl, 20, 48, 0, 255, 0, 255);307 _assertPixel(gl, 98, 48, 0, 255, 0, 255);308 });309 // arc() from 0 to pi draws stuff in the right half310 it('2d.path.arc.shape.2', function() {311 ctx.fillStyle = '#f00';312 ctx.fillRect(0, 0, 100, 50);313 ctx.lineWidth = 100;314 ctx.strokeStyle = '#0f0';315 ctx.beginPath();316 ctx.arc(50, 50, 50, 0, Math.PI, true);317 ctx.stroke();318 _assertPixel(gl, 50, 25, 0, 255, 0, 255);319 _assertPixel(gl, 1, 1, 0, 255, 0, 255);320 _assertPixel(gl, 98, 1, 0, 255, 0, 255);321 _assertPixel(gl, 1, 48, 0, 255, 0, 255);322 _assertPixel(gl, 20, 48, 0, 255, 0, 255);323 _assertPixel(gl, 98, 48, 0, 255, 0, 255);324 });325 // arc() from 0 to -pi/2 does not draw anything in the wrong quadrant326 it('2d.path.arc.shape.3', function() {327 ctx.fillStyle = '#0f0';328 ctx.fillRect(0, 0, 100, 50);329 ctx.lineWidth = 100;330 ctx.strokeStyle = '#f00';331 ctx.beginPath();332 ctx.arc(0, 50, 50, 0, -Math.PI / 2, false);333 ctx.stroke();334 _assertPixel(gl, 50, 25, 0, 255, 0, 255);335 _assertPixel(gl, 1, 1, 0, 255, 0, 255);336 _assertPixel(gl, 98, 1, 0, 255, 0, 255);337 _assertPixel(gl, 1, 48, 0, 255, 0, 255);338 _assertPixel(gl, 98, 48, 0, 255, 0, 255);339 });340 // arc() from 0 to -pi/2 draws stuff in the right quadrant341 it('2d.path.arc.shape.4', function() {342 ctx.fillStyle = '#f00';343 ctx.fillRect(0, 0, 100, 50);344 ctx.lineWidth = 150;345 ctx.strokeStyle = '#0f0';346 ctx.beginPath();347 ctx.arc(-50, 50, 100, 0, -Math.PI / 2, true);348 ctx.stroke();349 _assertPixel(gl, 50, 25, 0, 255, 0, 255);350 _assertPixel(gl, 1, 1, 0, 255, 0, 255);351 _assertPixel(gl, 98, 1, 0, 255, 0, 255);352 _assertPixel(gl, 1, 48, 0, 255, 0, 255);353 _assertPixel(gl, 98, 48, 0, 255, 0, 255);354 });355 // arc() from 0 to 5pi does not draw crazy things356 it('2d.path.arc.shape.5', function() {357 ctx.fillStyle = '#0f0';358 ctx.fillRect(0, 0, 100, 50);359 ctx.lineWidth = 200;360 ctx.strokeStyle = '#f00';361 ctx.beginPath();362 ctx.arc(300, 0, 100, 0, 5 * Math.PI, false);363 ctx.stroke();364 _assertPixel(gl, 50, 25, 0, 255, 0, 255);365 _assertPixel(gl, 1, 1, 0, 255, 0, 255);366 _assertPixel(gl, 98, 1, 0, 255, 0, 255);367 _assertPixel(gl, 1, 48, 0, 255, 0, 255);368 _assertPixel(gl, 98, 48, 0, 255, 0, 255);369 });370 // arc() with lineWidth > 2*radius is drawn sensibly371 it('2d.path.arc.selfintersect.1', function() {372 ctx.fillStyle = '#0f0';373 ctx.fillRect(0, 0, 100, 50);374 ctx.lineWidth = 200;375 ctx.strokeStyle = '#f00';376 ctx.beginPath();377 ctx.arc(100, 50, 25, 0, -Math.PI / 2, true);378 ctx.stroke();379 ctx.beginPath();380 ctx.arc(0, 0, 25, 0, -Math.PI / 2, true);381 ctx.stroke();382 _assertPixel(gl, 1, 1, 0, 255, 0, 255);383 _assertPixel(gl, 50, 25, 0, 255, 0, 255);384 });385 // arc() with lineWidth > 2*radius is drawn sensibly386 it('2d.path.arc.selfintersect.2', function() {387 ctx.fillStyle = '#f00';388 ctx.fillRect(0, 0, 100, 50);389 ctx.lineWidth = 180;390 ctx.strokeStyle = '#0f0';391 ctx.beginPath();392 ctx.arc(-50, 50, 25, 0, -Math.PI / 2, true);393 ctx.stroke();394 ctx.beginPath();395 ctx.arc(100, 0, 25, 0, -Math.PI / 2, true);396 ctx.stroke();397 _assertPixel(gl, 50, 25, 0, 255, 0, 255);398 _assertPixel(gl, 90, 10, 0, 255, 0, 255);399 _assertPixel(gl, 97, 1, 0, 255, 0, 255);400 _assertPixel(gl, 97, 2, 0, 255, 0, 255);401 _assertPixel(gl, 97, 3, 0, 255, 0, 255);402 _assertPixel(gl, 2, 48, 0, 255, 0, 255);403 });404 // arc() with negative radius throws INDEX_SIZE_ERR405 it('2d.path.arc.negative', function() {406 let fn = () => ctx.arc(0, 0, -1, 0, 0, true);407 assert.throws(fn, /The radius provided (.*) is negative/);408 });409 // arc() with zero radius draws a line to the start point410 it('2d.path.arc.zeroradius', function() {411 ctx.fillStyle = '#f00'412 ctx.fillRect(0, 0, 100, 50);413 ctx.lineWidth = 50;414 ctx.strokeStyle = '#0f0';415 ctx.beginPath();416 ctx.moveTo(0, 25);417 ctx.arc(200, 25, 0, 0, Math.PI, true);418 ctx.stroke();419 _assertPixel(gl, 50, 25, 0, 255, 0, 255);420 });421 // arc() with Infinity/NaN is ignored422 it('2d.path.arc.nonfinite', function() {423 ctx.fillStyle = '#f00';424 ctx.fillRect(0, 0, 100, 50);425 ctx.moveTo(0, 0);426 ctx.lineTo(100, 0);427 ctx.arc(Infinity, 0, 50, 0, 2*Math.PI, true);428 ctx.arc(-Infinity, 0, 50, 0, 2*Math.PI, true);429 ctx.arc(NaN, 0, 50, 0, 2*Math.PI, true);430 ctx.arc(0, Infinity, 50, 0, 2*Math.PI, true);431 ctx.arc(0, -Infinity, 50, 0, 2*Math.PI, true);432 ctx.arc(0, NaN, 50, 0, 2*Math.PI, true);433 ctx.arc(0, 0, Infinity, 0, 2*Math.PI, true);434 ctx.arc(0, 0, -Infinity, 0, 2*Math.PI, true);435 ctx.arc(0, 0, NaN, 0, 2*Math.PI, true);436 ctx.arc(0, 0, 50, Infinity, 2*Math.PI, true);437 ctx.arc(0, 0, 50, -Infinity, 2*Math.PI, true);438 ctx.arc(0, 0, 50, NaN, 2*Math.PI, true);439 ctx.arc(0, 0, 50, 0, Infinity, true);440 ctx.arc(0, 0, 50, 0, -Infinity, true);441 ctx.arc(0, 0, 50, 0, NaN, true);442 ctx.arc(Infinity, Infinity, 50, 0, 2*Math.PI, true);443 ctx.arc(Infinity, Infinity, Infinity, 0, 2*Math.PI, true);444 ctx.arc(Infinity, Infinity, Infinity, Infinity, 2*Math.PI, true);445 ctx.arc(Infinity, Infinity, Infinity, Infinity, Infinity, true);446 ctx.arc(Infinity, Infinity, Infinity, 0, Infinity, true);447 ctx.arc(Infinity, Infinity, 50, Infinity, 2*Math.PI, true);448 ctx.arc(Infinity, Infinity, 50, Infinity, Infinity, true);449 ctx.arc(Infinity, Infinity, 50, 0, Infinity, true);450 ctx.arc(Infinity, 0, Infinity, 0, 2*Math.PI, true);451 ctx.arc(Infinity, 0, Infinity, Infinity, 2*Math.PI, true);452 ctx.arc(Infinity, 0, Infinity, Infinity, Infinity, true);453 ctx.arc(Infinity, 0, Infinity, 0, Infinity, true);454 ctx.arc(Infinity, 0, 50, Infinity, 2*Math.PI, true);455 ctx.arc(Infinity, 0, 50, Infinity, Infinity, true);456 ctx.arc(Infinity, 0, 50, 0, Infinity, true);457 ctx.arc(0, Infinity, Infinity, 0, 2*Math.PI, true);458 ctx.arc(0, Infinity, Infinity, Infinity, 2*Math.PI, true);459 ctx.arc(0, Infinity, Infinity, Infinity, Infinity, true);460 ctx.arc(0, Infinity, Infinity, 0, Infinity, true);461 ctx.arc(0, Infinity, 50, Infinity, 2*Math.PI, true);462 ctx.arc(0, Infinity, 50, Infinity, Infinity, true);463 ctx.arc(0, Infinity, 50, 0, Infinity, true);464 ctx.arc(0, 0, Infinity, Infinity, 2*Math.PI, true);465 ctx.arc(0, 0, Infinity, Infinity, Infinity, true);466 ctx.arc(0, 0, Infinity, 0, Infinity, true);467 ctx.arc(0, 0, 50, Infinity, Infinity, true);468 ctx.lineTo(100, 50);469 ctx.lineTo(0, 50);470 ctx.fillStyle = '#0f0';471 ctx.fill();472 _assertPixel(gl, 50, 25, 0, 255, 0, 255);473 _assertPixel(gl, 90, 45, 0, 255, 0, 255);474 });475 it('MDN arc example', function() {476 var options = { width: 150, height: 200, fileName: this.test.fullTitle() };477 ({ gl, ctx } = _initContext(options));478 for (var i=0;i<4;i++) {479 for(var j=0;j<3;j++) {480 ctx.beginPath();481 var x = 25+j*50; // x coordinate482 var y = 25+i*50; // y coordinate483 var radius = 20; // Arc radius484 var startAngle = 0; // Starting point on circle485 var endAngle = Math.PI+(Math.PI*j)/2; // End point on circle486 var anticlockwise = i%2==1; // Draw anticlockwise487 488 ctx.arc(x,y,radius,startAngle,endAngle, anticlockwise);489 490 if (i>1){491 ctx.fill();492 } else {493 ctx.stroke();494 }495 }496 }497 _assertOutput(gl, options);498 })499})500describe('2d.lineWidth', function() {501 var gl, ctx;502 beforeEach(function() {503 ({ gl, ctx } = _initContext());504 });505 it('2d.line.width.basic', function() {506 ctx.fillStyle = '#0f0';507 ctx.fillRect(0, 0, 100, 50);508 ctx.lineWidth = 20;509 // Draw a green line over a red box, to check the line is not too small510 ctx.fillStyle = '#f00';511 ctx.strokeStyle = '#0f0';512 ctx.fillRect(15, 15, 20, 20);513 ctx.beginPath();514 ctx.moveTo(25, 15);515 ctx.lineTo(25, 35);516 ctx.stroke();517 // Draw a green box over a red line, to check the line is not too large518 ctx.fillStyle = '#0f0';519 ctx.strokeStyle = '#f00';520 ctx.beginPath();521 ctx.moveTo(75, 15);522 ctx.lineTo(75, 35);523 ctx.stroke();524 ctx.fillRect(65, 15, 20, 20);525 _assertPixel(gl, 14, 25, 0, 255, 0, 255);526 _assertPixel(gl, 15, 25, 0, 255, 0, 255);527 _assertPixel(gl, 16, 25, 0, 255, 0, 255);528 _assertPixel(gl, 25, 25, 0, 255, 0, 255);529 _assertPixel(gl, 34, 25, 0, 255, 0, 255);530 _assertPixel(gl, 35, 25, 0, 255, 0, 255);531 _assertPixel(gl, 36, 25, 0, 255, 0, 255);532 _assertPixel(gl, 64, 25, 0, 255, 0, 255);533 _assertPixel(gl, 65, 25, 0, 255, 0, 255);534 _assertPixel(gl, 66, 25, 0, 255, 0, 255);535 _assertPixel(gl, 75, 25, 0, 255, 0, 255);536 _assertPixel(gl, 84, 25, 0, 255, 0, 255);537 _assertPixel(gl, 85, 25, 0, 255, 0, 255);538 _assertPixel(gl, 86, 25, 0, 255, 0, 255);539 })540})541function _assertOutput(gl, { width = 100, height = 50, fileName } = {}) {542 var pixels = new Uint8Array(width * height * 4)543 gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels)544 545 fileName = `./test/assets/${fileName}.png`;546 var pngData = fs.readFileSync(fileName);547 var expectedData = PNG.sync.read(pngData).data;548 var compResult = expectedData.compare(Buffer.from(pixels));549 assert(compResult == 0, 'Output does not match the expected file');550}551function _getPixel(gl, x, y) {552 const width = 1,553 height = 1;554 var pixels = new Uint8Array(width * height * 4);555 gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);556 return pixels;557}558function _assertPixel(gl, x, y, r, g, b, a) {559 var c = _getPixel(gl, x, y);560 assert.equal(c[0], r, 'Red channel of the pixel at (' + x + ', ' + y + ')');561 assert.equal(c[1], g, 'Green channel of the pixel at (' + x + ', ' + y + ')');562 assert.equal(c[2], b, 'Blue channel of the pixel at (' + x + ', ' + y + ')');563 assert.equal(c[3], a, 'Alpha channel of the pixel at (' + x + ', ' + y + ')');564}565function _initContext(options) {566 var options = options || {};567 //Create context568 var width = options.width || 100;569 var height = options.height || 50;570 var gl = require('gl')(width, height, { preserveDrawingBuffer: true });571 var ctx = new CanvasRenderingContext2D(gl, width, height);572 return { gl, ctx };...
Using AI Code Generation
1var wpt = require('wptdriver');2wpt._assertPixel(0, 0, 255, 0, 0, 1);3wpt._assertPixel(0, 0, 0, 0, 0, 1);4wpt._assertPixel(0, 0, 0, 0, 0, 0);5 <canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;">6 var c = document.getElementById("myCanvas");7 var ctx = c.getContext("2d");8 ctx.fillStyle = "#FF0000";9 ctx.fillRect(0, 0, 150, 75);10var wpt = require('wptdriver');11wpt._assertPixel(0, 0, 255, 0, 0, 1);12wpt._assertPixel(0, 0, 0, 0, 0, 1);13wpt._assertPixel(0, 0, 0, 0, 0, 0);14 <canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;">15 var c = document.getElementById("myCanvas");16 var ctx = c.getContext("2d");17 ctx.fillStyle = "#FF0000";18 ctx.fillRect(0, 0, 150, 75);19var wpt = require('wptdriver');20wpt._assertPixel(0, 0, 255, 0, 0, 1);21wpt._assertPixel(0, 0, 0, 0, 0, 1);
Using AI Code Generation
1var assertPixel = require('wptdriver').assertPixel;2assertPixel(1, 1, [255, 0, 0, 255], 'red pixel');3var assertPixels = require('wptdriver').assertPixels;4assertPixels([5]);6var assertImage = require('wptdriver').assertImage;7assertImage('images/expected.png', 'images/actual.png', 'images/diff.png', 'images/threshold.png');8[MIT](LICENSE)
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!