shadows.yaml (30799B)
1 - name: 2d.shadow.attributes.shadowBlur.initial 2 code: | 3 @assert ctx.shadowBlur === 0; 4 5 - name: 2d.shadow.attributes.shadowBlur.valid 6 code: | 7 ctx.shadowBlur = 1; 8 @assert ctx.shadowBlur === 1; 9 10 ctx.shadowBlur = 0.5; 11 @assert ctx.shadowBlur === 0.5; 12 13 ctx.shadowBlur = 1e6; 14 @assert ctx.shadowBlur === 1e6; 15 16 ctx.shadowBlur = 0; 17 @assert ctx.shadowBlur === 0; 18 19 - name: 2d.shadow.attributes.shadowBlur.invalid 20 code: | 21 ctx.shadowBlur = 1; 22 ctx.shadowBlur = -2; 23 @assert ctx.shadowBlur === 1; 24 25 ctx.shadowBlur = 1; 26 ctx.shadowBlur = Infinity; 27 @assert ctx.shadowBlur === 1; 28 29 ctx.shadowBlur = 1; 30 ctx.shadowBlur = -Infinity; 31 @assert ctx.shadowBlur === 1; 32 33 ctx.shadowBlur = 1; 34 ctx.shadowBlur = NaN; 35 @assert ctx.shadowBlur === 1; 36 37 ctx.shadowBlur = 1; 38 ctx.shadowBlur = 'string'; 39 @assert ctx.shadowBlur === 1; 40 41 ctx.shadowBlur = 1; 42 ctx.shadowBlur = true; 43 @assert ctx.shadowBlur === 1; 44 45 ctx.shadowBlur = 1; 46 ctx.shadowBlur = false; 47 @assert ctx.shadowBlur === 0; 48 49 - name: 2d.shadow.attributes.shadowOffset.initial 50 code: | 51 @assert ctx.shadowOffsetX === 0; 52 @assert ctx.shadowOffsetY === 0; 53 54 - name: 2d.shadow.attributes.shadowOffset.valid 55 code: | 56 ctx.shadowOffsetX = 1; 57 ctx.shadowOffsetY = 2; 58 @assert ctx.shadowOffsetX === 1; 59 @assert ctx.shadowOffsetY === 2; 60 61 ctx.shadowOffsetX = 0.5; 62 ctx.shadowOffsetY = 0.25; 63 @assert ctx.shadowOffsetX === 0.5; 64 @assert ctx.shadowOffsetY === 0.25; 65 66 ctx.shadowOffsetX = -0.5; 67 ctx.shadowOffsetY = -0.25; 68 @assert ctx.shadowOffsetX === -0.5; 69 @assert ctx.shadowOffsetY === -0.25; 70 71 ctx.shadowOffsetX = 0; 72 ctx.shadowOffsetY = 0; 73 @assert ctx.shadowOffsetX === 0; 74 @assert ctx.shadowOffsetY === 0; 75 76 ctx.shadowOffsetX = 1e6; 77 ctx.shadowOffsetY = 1e6; 78 @assert ctx.shadowOffsetX === 1e6; 79 @assert ctx.shadowOffsetY === 1e6; 80 81 - name: 2d.shadow.attributes.shadowOffset.invalid 82 code: | 83 ctx.shadowOffsetX = 1; 84 ctx.shadowOffsetY = 2; 85 ctx.shadowOffsetX = Infinity; 86 ctx.shadowOffsetY = Infinity; 87 @assert ctx.shadowOffsetX === 1; 88 @assert ctx.shadowOffsetY === 2; 89 90 ctx.shadowOffsetX = 1; 91 ctx.shadowOffsetY = 2; 92 ctx.shadowOffsetX = -Infinity; 93 ctx.shadowOffsetY = -Infinity; 94 @assert ctx.shadowOffsetX === 1; 95 @assert ctx.shadowOffsetY === 2; 96 97 ctx.shadowOffsetX = 1; 98 ctx.shadowOffsetY = 2; 99 ctx.shadowOffsetX = NaN; 100 ctx.shadowOffsetY = NaN; 101 @assert ctx.shadowOffsetX === 1; 102 @assert ctx.shadowOffsetY === 2; 103 104 ctx.shadowOffsetX = 1; 105 ctx.shadowOffsetY = 2; 106 ctx.shadowOffsetX = 'string'; 107 ctx.shadowOffsetY = 'string'; 108 @assert ctx.shadowOffsetX === 1; 109 @assert ctx.shadowOffsetY === 2; 110 111 ctx.shadowOffsetX = 1; 112 ctx.shadowOffsetY = 2; 113 ctx.shadowOffsetX = true; 114 ctx.shadowOffsetY = true; 115 @assert ctx.shadowOffsetX === 1; 116 @assert ctx.shadowOffsetY === 1; 117 118 ctx.shadowOffsetX = 1; 119 ctx.shadowOffsetY = 2; 120 ctx.shadowOffsetX = false; 121 ctx.shadowOffsetY = false; 122 @assert ctx.shadowOffsetX === 0; 123 @assert ctx.shadowOffsetY === 0; 124 125 - name: 2d.shadow.attributes.shadowColor.initial 126 code: | 127 @assert ctx.shadowColor === 'rgba(0, 0, 0, 0)'; 128 129 - name: 2d.shadow.attributes.shadowColor.valid 130 code: | 131 ctx.shadowColor = 'lime'; 132 @assert ctx.shadowColor === '#00ff00'; 133 134 ctx.shadowColor = 'RGBA(0,255, 0,0)'; 135 @assert ctx.shadowColor === 'rgba(0, 255, 0, 0)'; 136 137 - name: 2d.shadow.attributes.shadowColor.current.basic 138 desc: currentColor is computed from the canvas element 139 canvas_types: ['HtmlCanvas'] 140 code: | 141 canvas.style.color = '#0f0'; 142 ctx.shadowColor = 'currentColor'; 143 @assert ctx.shadowColor === '#00ff00'; 144 145 - name: 2d.shadow.attributes.shadowColor.current.changed 146 desc: currentColor is computed when the attribute is set, not when it is painted 147 canvas_types: ['HtmlCanvas'] 148 code: | 149 canvas.style.color = '#0f0'; 150 ctx.shadowColor = 'currentColor'; 151 canvas.style.color = '#f00'; 152 @assert ctx.shadowColor === '#00ff00'; 153 154 - name: 2d.shadow.attributes.shadowColor.current.removed 155 desc: currentColor is solid black when the canvas element is not in a document 156 canvas_types: ['HtmlCanvas'] 157 code: | 158 // Try not to let it undetectably incorrectly pick up opaque-black 159 // from other parts of the document: 160 document.documentElement.style.color = '#f00'; 161 document.body.style.color = '#f00'; 162 canvas.style.color = '#f00'; 163 164 canvas.remove(); 165 ctx.shadowColor = 'currentColor'; 166 @assert ctx.shadowColor === '#000000'; 167 168 - name: 2d.shadow.attributes.shadowColor.invalid 169 code: | 170 ctx.shadowColor = '#00ff00'; 171 ctx.shadowColor = 'bogus'; 172 @assert ctx.shadowColor === '#00ff00'; 173 174 ctx.shadowColor = '#00ff00'; 175 ctx.shadowColor = 'red bogus'; 176 @assert ctx.shadowColor === '#00ff00'; 177 178 ctx.shadowColor = '#00ff00'; 179 ctx.shadowColor = ctx; 180 @assert ctx.shadowColor === '#00ff00'; 181 182 ctx.shadowColor = '#00ff00'; 183 ctx.shadowColor = undefined; 184 @assert ctx.shadowColor === '#00ff00'; 185 186 - name: 2d.shadow.enable.off.1 187 desc: Shadows are not drawn when only shadowColor is set 188 code: | 189 ctx.shadowColor = '#f00'; 190 ctx.fillStyle = '#0f0'; 191 ctx.fillRect(0, 0, 100, 50); 192 @assert pixel 50,25 == 0,255,0,255; 193 expected: green 194 195 - name: 2d.shadow.enable.off.2 196 desc: Shadows are not drawn when only shadowColor is set 197 code: | 198 ctx.globalCompositeOperation = 'destination-atop'; 199 ctx.shadowColor = '#f00'; 200 ctx.fillStyle = '#0f0'; 201 ctx.fillRect(0, 0, 100, 50); 202 @assert pixel 50,25 == 0,255,0,255; 203 expected: green 204 205 - name: 2d.shadow.enable.blur 206 desc: Shadows are drawn if shadowBlur is set 207 code: | 208 ctx.globalCompositeOperation = 'destination-atop'; 209 ctx.shadowColor = '#0f0'; 210 ctx.shadowBlur = 0.1; 211 ctx.fillStyle = '#f00'; 212 ctx.fillRect(0, 0, 100, 50); 213 @assert pixel 50,25 == 0,255,0,255; 214 expected: green 215 216 - name: 2d.shadow.enable.x 217 desc: Shadows are drawn if shadowOffsetX is set 218 code: | 219 ctx.globalCompositeOperation = 'destination-atop'; 220 ctx.shadowColor = '#0f0'; 221 ctx.shadowOffsetX = 0.1; 222 ctx.fillStyle = '#f00'; 223 ctx.fillRect(0, 0, 100, 50); 224 @assert pixel 50,25 == 0,255,0,255; 225 expected: green 226 227 - name: 2d.shadow.enable.y 228 desc: Shadows are drawn if shadowOffsetY is set 229 code: | 230 ctx.globalCompositeOperation = 'destination-atop'; 231 ctx.shadowColor = '#0f0'; 232 ctx.shadowOffsetY = 0.1; 233 ctx.fillStyle = '#f00'; 234 ctx.fillRect(0, 0, 100, 50); 235 @assert pixel 50,25 == 0,255,0,255; 236 expected: green 237 238 - name: 2d.shadow.offset.positiveX 239 desc: Shadows can be offset with positive x 240 code: | 241 ctx.fillStyle = '#f00'; 242 ctx.fillRect(0, 0, 100, 50); 243 ctx.fillStyle = '#0f0'; 244 ctx.shadowColor = '#0f0'; 245 ctx.shadowOffsetX = 50; 246 ctx.fillRect(0, 0, 50, 50); 247 @assert pixel 25,25 == 0,255,0,255; 248 @assert pixel 75,25 == 0,255,0,255; 249 expected: green 250 251 - name: 2d.shadow.offset.negativeX 252 desc: Shadows can be offset with negative x 253 code: | 254 ctx.fillStyle = '#f00'; 255 ctx.fillRect(0, 0, 100, 50); 256 ctx.fillStyle = '#0f0'; 257 ctx.shadowColor = '#0f0'; 258 ctx.shadowOffsetX = -50; 259 ctx.fillRect(50, 0, 50, 50); 260 @assert pixel 25,25 == 0,255,0,255; 261 @assert pixel 75,25 == 0,255,0,255; 262 expected: green 263 264 - name: 2d.shadow.offset.positiveY 265 desc: Shadows can be offset with positive y 266 code: | 267 ctx.fillStyle = '#f00'; 268 ctx.fillRect(0, 0, 100, 50); 269 ctx.fillStyle = '#0f0'; 270 ctx.shadowColor = '#0f0'; 271 ctx.shadowOffsetY = 25; 272 ctx.fillRect(0, 0, 100, 25); 273 @assert pixel 50,12 == 0,255,0,255; 274 @assert pixel 50,37 == 0,255,0,255; 275 expected: green 276 277 - name: 2d.shadow.offset.negativeY 278 desc: Shadows can be offset with negative y 279 code: | 280 ctx.fillStyle = '#f00'; 281 ctx.fillRect(0, 0, 100, 50); 282 ctx.fillStyle = '#0f0'; 283 ctx.shadowColor = '#0f0'; 284 ctx.shadowOffsetY = -25; 285 ctx.fillRect(0, 25, 100, 25); 286 @assert pixel 50,12 == 0,255,0,255; 287 @assert pixel 50,37 == 0,255,0,255; 288 expected: green 289 290 - name: 2d.shadow.outside 291 desc: Shadows of shapes outside the visible area can be offset onto the visible 292 area 293 code: | 294 ctx.fillStyle = '#f00'; 295 ctx.fillRect(0, 0, 100, 50); 296 ctx.shadowColor = '#0f0'; 297 ctx.shadowOffsetX = 100; 298 ctx.fillRect(-100, 0, 25, 50); 299 ctx.shadowOffsetX = -100; 300 ctx.fillRect(175, 0, 25, 50); 301 ctx.shadowOffsetX = 0; 302 ctx.shadowOffsetY = 100; 303 ctx.fillRect(25, -100, 50, 25); 304 ctx.shadowOffsetY = -100; 305 ctx.fillRect(25, 125, 50, 25); 306 @assert pixel 12,25 == 0,255,0,255; 307 @assert pixel 87,25 == 0,255,0,255; 308 @assert pixel 50,12 == 0,255,0,255; 309 @assert pixel 50,37 == 0,255,0,255; 310 expected: green 311 312 - name: 2d.shadow.clip.1 313 desc: Shadows of clipped shapes are still drawn within the clipping region 314 code: | 315 ctx.fillStyle = '#0f0'; 316 ctx.fillRect(0, 0, 50, 50); 317 ctx.fillStyle = '#f00'; 318 ctx.fillRect(50, 0, 50, 50); 319 320 ctx.save(); 321 ctx.beginPath(); 322 ctx.rect(50, 0, 50, 50); 323 ctx.clip(); 324 ctx.shadowColor = '#0f0'; 325 ctx.shadowOffsetX = 50; 326 ctx.fillRect(0, 0, 50, 50); 327 ctx.restore(); 328 329 @assert pixel 25,25 == 0,255,0,255; 330 @assert pixel 75,25 == 0,255,0,255; 331 expected: green 332 333 - name: 2d.shadow.clip.2 334 desc: Shadows are not drawn outside the clipping region 335 code: | 336 ctx.fillStyle = '#f00'; 337 ctx.fillRect(0, 0, 50, 50); 338 ctx.fillStyle = '#0f0'; 339 ctx.fillRect(50, 0, 50, 50); 340 341 ctx.save(); 342 ctx.beginPath(); 343 ctx.rect(0, 0, 50, 50); 344 ctx.clip(); 345 ctx.shadowColor = '#f00'; 346 ctx.shadowOffsetX = 50; 347 ctx.fillRect(0, 0, 50, 50); 348 ctx.restore(); 349 350 @assert pixel 25,25 == 0,255,0,255; 351 @assert pixel 75,25 == 0,255,0,255; 352 expected: green 353 354 - name: 2d.shadow.clip.3 355 desc: Shadows of clipped shapes are still drawn within the clipping region 356 code: | 357 ctx.fillStyle = '#f00'; 358 ctx.fillRect(0, 0, 50, 50); 359 ctx.fillStyle = '#0f0'; 360 ctx.fillRect(50, 0, 50, 50); 361 362 ctx.save(); 363 ctx.beginPath(); 364 ctx.rect(0, 0, 50, 50); 365 ctx.clip(); 366 ctx.fillStyle = '#f00'; 367 ctx.shadowColor = '#0f0'; 368 ctx.shadowOffsetX = 50; 369 ctx.fillRect(-50, 0, 50, 50); 370 ctx.restore(); 371 372 @assert pixel 25,25 == 0,255,0,255; 373 @assert pixel 75,25 == 0,255,0,255; 374 expected: green 375 376 - name: 2d.shadow.stroke.basic 377 desc: Shadows are drawn for strokes 378 code: | 379 ctx.fillStyle = '#f00'; 380 ctx.fillRect(0, 0, 100, 50); 381 ctx.strokeStyle = '#f00'; 382 ctx.shadowColor = '#0f0'; 383 ctx.shadowOffsetY = 50; 384 ctx.beginPath(); 385 ctx.lineWidth = 50; 386 ctx.moveTo(0, -25); 387 ctx.lineTo(100, -25); 388 ctx.stroke(); 389 390 @assert pixel 1,25 == 0,255,0,255; 391 @assert pixel 50,25 == 0,255,0,255; 392 @assert pixel 98,25 == 0,255,0,255; 393 expected: green 394 395 - name: 2d.shadow.stroke.cap.1 396 desc: Shadows are not drawn for areas outside stroke caps 397 code: | 398 ctx.fillStyle = '#0f0'; 399 ctx.fillRect(0, 0, 100, 50); 400 ctx.strokeStyle = '#f00'; 401 ctx.shadowColor = '#f00'; 402 ctx.shadowOffsetY = 50; 403 ctx.beginPath(); 404 ctx.lineWidth = 50; 405 ctx.lineCap = 'butt'; 406 ctx.moveTo(-50, -25); 407 ctx.lineTo(0, -25); 408 ctx.moveTo(100, -25); 409 ctx.lineTo(150, -25); 410 ctx.stroke(); 411 412 @assert pixel 1,25 == 0,255,0,255; 413 @assert pixel 50,25 == 0,255,0,255; 414 @assert pixel 98,25 == 0,255,0,255; 415 expected: green 416 417 - name: 2d.shadow.stroke.cap.2 418 desc: Shadows are drawn for stroke caps 419 code: | 420 ctx.fillStyle = '#f00'; 421 ctx.fillRect(0, 0, 100, 50); 422 ctx.strokeStyle = '#f00'; 423 ctx.shadowColor = '#0f0'; 424 ctx.shadowOffsetY = 50; 425 ctx.beginPath(); 426 ctx.lineWidth = 50; 427 ctx.lineCap = 'square'; 428 ctx.moveTo(25, -25); 429 ctx.lineTo(75, -25); 430 ctx.stroke(); 431 432 @assert pixel 1,25 == 0,255,0,255; 433 @assert pixel 50,25 == 0,255,0,255; 434 @assert pixel 98,25 == 0,255,0,255; 435 expected: green 436 437 - name: 2d.shadow.stroke.join.1 438 desc: Shadows are not drawn for areas outside stroke joins 439 code: | 440 ctx.fillStyle = '#0f0'; 441 ctx.fillRect(0, 0, 100, 50); 442 ctx.strokeStyle = '#f00'; 443 ctx.shadowColor = '#f00'; 444 ctx.shadowOffsetX = 100; 445 ctx.lineWidth = 200; 446 ctx.lineJoin = 'bevel'; 447 ctx.beginPath(); 448 ctx.moveTo(-200, -50); 449 ctx.lineTo(-150, -50); 450 ctx.lineTo(-151, -100); 451 ctx.stroke(); 452 453 @assert pixel 1,1 == 0,255,0,255; 454 @assert pixel 48,48 == 0,255,0,255; 455 @assert pixel 50,25 == 0,255,0,255; 456 @assert pixel 98,48 == 0,255,0,255; 457 expected: green 458 459 - name: 2d.shadow.stroke.join.2 460 desc: Shadows are drawn for stroke joins 461 code: | 462 ctx.fillStyle = '#f00'; 463 ctx.fillRect(0, 0, 50, 50); 464 ctx.fillStyle = '#0f0'; 465 ctx.fillRect(50, 0, 50, 50); 466 ctx.strokeStyle = '#f00'; 467 ctx.shadowColor = '#0f0'; 468 ctx.shadowOffsetX = 100; 469 ctx.lineWidth = 200; 470 ctx.lineJoin = 'miter'; 471 ctx.beginPath(); 472 ctx.moveTo(-200, -50); 473 ctx.lineTo(-150, -50); 474 ctx.lineTo(-151, -100); 475 ctx.stroke(); 476 477 @assert pixel 1,1 == 0,255,0,255; 478 @assert pixel 48,48 == 0,255,0,255; 479 @assert pixel 50,25 == 0,255,0,255; 480 @assert pixel 98,48 == 0,255,0,255; 481 expected: green 482 483 - name: 2d.shadow.stroke.join.3 484 desc: Shadows are drawn for stroke joins respecting miter limit 485 code: | 486 ctx.fillStyle = '#0f0'; 487 ctx.fillRect(0, 0, 100, 50); 488 ctx.strokeStyle = '#f00'; 489 ctx.shadowColor = '#f00'; 490 ctx.shadowOffsetX = 100; 491 ctx.lineWidth = 200; 492 ctx.lineJoin = 'miter'; 493 ctx.miterLimit = 0.1; 494 ctx.beginPath(); 495 ctx.moveTo(-200, -50); 496 ctx.lineTo(-150, -50); 497 ctx.lineTo(-151, -100); // (not an exact right angle, to avoid some other bug in Firefox 3) 498 ctx.stroke(); 499 500 @assert pixel 1,1 == 0,255,0,255; 501 @assert pixel 48,48 == 0,255,0,255; 502 @assert pixel 50,25 == 0,255,0,255; 503 @assert pixel 98,48 == 0,255,0,255; 504 expected: green 505 506 - name: 2d.shadow.image.basic 507 desc: Shadows are drawn for images 508 images: 509 - red.png 510 code: | 511 ctx.fillStyle = '#f00'; 512 ctx.fillRect(0, 0, 100, 50); 513 ctx.shadowColor = '#0f0'; 514 ctx.shadowOffsetY = 50; 515 {{ load_image }} 516 ctx.drawImage(img, 0, -50); 517 518 @assert pixel 50,25 == 0,255,0,255; 519 expected: green 520 variants: &load-image-variant-definition 521 - HtmlCanvas: 522 append_variants_to_name: false 523 canvas_types: ['HtmlCanvas'] 524 load_image: var img = document.getElementById('{{ images[0] }}'); 525 OffscreenCanvas: 526 append_variants_to_name: false 527 canvas_types: ['OffscreenCanvas', 'Worker'] 528 test_type: promise 529 load_image: |- 530 var response = await fetch('/images/{{ images[0] }}') 531 var blob = await response.blob(); 532 var img = await createImageBitmap(blob); 533 534 - name: 2d.shadow.image.transparent.1 535 desc: Shadows are not drawn for transparent images 536 images: 537 - transparent.png 538 code: | 539 ctx.fillStyle = '#0f0'; 540 ctx.fillRect(0, 0, 100, 50); 541 ctx.shadowColor = '#f00'; 542 ctx.shadowOffsetY = 50; 543 {{ load_image }} 544 ctx.drawImage(img, 0, -50); 545 546 @assert pixel 50,25 == 0,255,0,255; 547 expected: green 548 variants: *load-image-variant-definition 549 550 - name: 2d.shadow.image.transparent.2 551 desc: Shadows are not drawn for transparent parts of images 552 images: 553 - redtransparent.png 554 code: | 555 ctx.fillStyle = '#0f0'; 556 ctx.fillRect(0, 0, 50, 50); 557 ctx.fillStyle = '#f00'; 558 ctx.fillRect(50, 0, 50, 50); 559 ctx.shadowOffsetY = 50; 560 ctx.shadowColor = '#0f0'; 561 {{ load_image }} 562 ctx.drawImage(img, 50, -50); 563 ctx.shadowColor = '#f00'; 564 ctx.drawImage(img, -50, -50); 565 566 @assert pixel 25,25 == 0,255,0,255; 567 @assert pixel 50,25 == 0,255,0,255; 568 @assert pixel 75,25 == 0,255,0,255; 569 expected: green 570 variants: *load-image-variant-definition 571 572 - name: 2d.shadow.image.alpha 573 desc: Shadows are drawn correctly for partially-transparent images 574 images: 575 - transparent50.png 576 code: | 577 ctx.fillStyle = '#f00'; 578 ctx.fillRect(0, 0, 100, 50); 579 ctx.shadowOffsetY = 50; 580 ctx.shadowColor = '#00f'; 581 {{ load_image }} 582 ctx.drawImage(img, 0, -50); 583 584 @assert pixel 50,25 ==~ 127,0,127,255; 585 expected: | 586 size 100 50 587 cr.set_source_rgb(0.5, 0, 0.5) 588 cr.rectangle(0, 0, 100, 50) 589 cr.fill() 590 variants: *load-image-variant-definition 591 592 - name: 2d.shadow.image.section 593 desc: Shadows are not drawn for areas outside image source rectangles 594 images: 595 - redtransparent.png 596 code: | 597 ctx.fillStyle = '#0f0'; 598 ctx.fillRect(0, 0, 100, 50); 599 ctx.shadowOffsetY = 50; 600 ctx.shadowColor = '#f00'; 601 {{ load_image }} 602 ctx.drawImage(img, 50, 0, 50, 50, 0, -50, 50, 50); 603 604 @assert pixel 25,25 ==~ 0,255,0,255; 605 @assert pixel 50,25 ==~ 0,255,0,255; 606 @assert pixel 75,25 ==~ 0,255,0,255; 607 expected: green 608 variants: *load-image-variant-definition 609 610 - name: 2d.shadow.image.scale 611 desc: Shadows are drawn correctly for scaled images 612 images: 613 - redtransparent.png 614 code: | 615 ctx.fillStyle = '#f00'; 616 ctx.fillRect(0, 0, 100, 50); 617 ctx.shadowOffsetY = 50; 618 ctx.shadowColor = '#0f0'; 619 {{ load_image }} 620 ctx.drawImage(img, 0, 0, 100, 50, -10, -50, 240, 50); 621 622 @assert pixel 25,25 ==~ 0,255,0,255; 623 @assert pixel 50,25 ==~ 0,255,0,255; 624 @assert pixel 75,25 ==~ 0,255,0,255; 625 expected: green 626 variants: *load-image-variant-definition 627 628 - name: 2d.shadow.canvas.basic 629 desc: Shadows are drawn for canvases 630 code: | 631 {{ create_canvas2 }} 632 var ctx2 = canvas2.getContext('2d'); 633 ctx2.fillStyle = '#f00'; 634 ctx2.fillRect(0, 0, 100, 50); 635 636 ctx.fillStyle = '#f00'; 637 ctx.fillRect(0, 0, 100, 50); 638 ctx.shadowColor = '#0f0'; 639 ctx.shadowOffsetY = 50; 640 ctx.drawImage(canvas2, 0, -50); 641 642 @assert pixel 50,25 == 0,255,0,255; 643 expected: green 644 variants: &create-canvas2-variant-definition 645 - HtmlCanvas: 646 append_variants_to_name: false 647 canvas_types: ['HtmlCanvas'] 648 create_canvas2: |- 649 var canvas2 = document.createElement('canvas'); 650 canvas2.width = 100; 651 canvas2.height = 50; 652 OffscreenCanvas: 653 append_variants_to_name: false 654 canvas_types: ['OffscreenCanvas', 'Worker'] 655 create_canvas2: |- 656 var canvas2 = new OffscreenCanvas(100, 50); 657 658 - name: 2d.shadow.canvas.transparent.1 659 desc: Shadows are not drawn for transparent canvases 660 code: | 661 {{ create_canvas2 }} 662 var ctx2 = canvas2.getContext('2d'); 663 664 ctx.fillStyle = '#0f0'; 665 ctx.fillRect(0, 0, 100, 50); 666 ctx.shadowColor = '#f00'; 667 ctx.shadowOffsetY = 50; 668 ctx.drawImage(canvas2, 0, -50); 669 670 @assert pixel 50,25 == 0,255,0,255; 671 expected: green 672 variants: *create-canvas2-variant-definition 673 674 - name: 2d.shadow.canvas.transparent.2 675 desc: Shadows are not drawn for transparent parts of canvases 676 code: | 677 {{ create_canvas2 }} 678 var ctx2 = canvas2.getContext('2d'); 679 ctx2.fillStyle = '#f00'; 680 ctx2.fillRect(0, 0, 50, 50); 681 682 ctx.fillStyle = '#0f0'; 683 ctx.fillRect(0, 0, 50, 50); 684 ctx.fillStyle = '#f00'; 685 ctx.fillRect(50, 0, 50, 50); 686 ctx.shadowOffsetY = 50; 687 ctx.shadowColor = '#0f0'; 688 ctx.drawImage(canvas2, 50, -50); 689 ctx.shadowColor = '#f00'; 690 ctx.drawImage(canvas2, -50, -50); 691 692 @assert pixel 25,25 == 0,255,0,255; 693 @assert pixel 50,25 == 0,255,0,255; 694 @assert pixel 75,25 == 0,255,0,255; 695 expected: green 696 variants: *create-canvas2-variant-definition 697 698 - name: 2d.shadow.canvas.alpha 699 desc: Shadows are drawn correctly for partially-transparent canvases 700 code: | 701 {{ create_canvas2 }} 702 var ctx2 = canvas2.getContext('2d'); 703 ctx2.fillStyle = 'rgba(255, 0, 0, 0.5)'; 704 ctx2.fillRect(0, 0, 100, 50); 705 706 ctx.fillStyle = '#f00'; 707 ctx.fillRect(0, 0, 100, 50); 708 ctx.shadowOffsetY = 50; 709 ctx.shadowColor = '#00f'; 710 ctx.drawImage(canvas2, 0, -50); 711 712 @assert pixel 50,25 ==~ 127,0,127,255; 713 expected: | 714 size 100 50 715 cr.set_source_rgb(0.5, 0, 0.5) 716 cr.rectangle(0, 0, 100, 50) 717 cr.fill() 718 variants: *create-canvas2-variant-definition 719 720 - name: 2d.shadow.pattern.basic 721 desc: Shadows are drawn for fill patterns 722 # http://bugs.webkit.org/show_bug.cgi?id=15266 723 images: 724 - red.png 725 code: | 726 {{ load_image }} 727 var pattern = ctx.createPattern(img, 'repeat'); 728 ctx.fillStyle = '#f00'; 729 ctx.fillRect(0, 0, 100, 50); 730 ctx.shadowColor = '#0f0'; 731 ctx.shadowOffsetY = 50; 732 ctx.fillStyle = pattern; 733 ctx.fillRect(0, -50, 100, 50); 734 735 @assert pixel 50,25 == 0,255,0,255; 736 expected: green 737 variants: *load-image-variant-definition 738 739 - name: 2d.shadow.pattern.transparent.1 740 desc: Shadows are not drawn for transparent fill patterns 741 # http://bugs.webkit.org/show_bug.cgi?id=15266 742 images: 743 - transparent.png 744 code: | 745 {{ load_image }} 746 var pattern = ctx.createPattern(img, 'repeat'); 747 ctx.fillStyle = '#0f0'; 748 ctx.fillRect(0, 0, 100, 50); 749 ctx.shadowColor = '#f00'; 750 ctx.shadowOffsetY = 50; 751 ctx.fillStyle = pattern; 752 ctx.fillRect(0, -50, 100, 50); 753 754 @assert pixel 50,25 == 0,255,0,255; 755 expected: green 756 variants: *load-image-variant-definition 757 758 - name: 2d.shadow.pattern.transparent.2 759 desc: Shadows are not drawn for transparent parts of fill patterns 760 # http://bugs.webkit.org/show_bug.cgi?id=15266 761 images: 762 - redtransparent.png 763 code: | 764 {{ load_image }} 765 var pattern = ctx.createPattern(img, 'repeat'); 766 ctx.fillStyle = '#f00'; 767 ctx.fillRect(0, 0, 50, 50); 768 ctx.fillStyle = '#0f0'; 769 ctx.fillRect(50, 0, 50, 50); 770 ctx.shadowOffsetY = 50; 771 ctx.shadowColor = '#0f0'; 772 ctx.fillStyle = pattern; 773 ctx.fillRect(0, -50, 100, 50); 774 775 @assert pixel 25,25 == 0,255,0,255; 776 @assert pixel 50,25 == 0,255,0,255; 777 @assert pixel 75,25 == 0,255,0,255; 778 expected: green 779 variants: *load-image-variant-definition 780 781 - name: 2d.shadow.pattern.alpha 782 desc: Shadows are drawn correctly for partially-transparent fill patterns 783 # http://bugs.webkit.org/show_bug.cgi?id=15266 784 images: 785 - transparent50.png 786 code: | 787 {{ load_image }} 788 var pattern = ctx.createPattern(img, 'repeat'); 789 ctx.fillStyle = '#f00'; 790 ctx.fillRect(0, 0, 100, 50); 791 ctx.shadowOffsetY = 50; 792 ctx.shadowColor = '#00f'; 793 ctx.fillStyle = pattern; 794 ctx.fillRect(0, -50, 100, 50); 795 796 @assert pixel 50,25 ==~ 127,0,127,255; 797 expected: | 798 size 100 50 799 cr.set_source_rgb(0.5, 0, 0.5) 800 cr.rectangle(0, 0, 100, 50) 801 cr.fill() 802 variants: *load-image-variant-definition 803 804 - name: 2d.shadow.gradient.basic 805 desc: Shadows are drawn for gradient fills 806 # http://bugs.webkit.org/show_bug.cgi?id=15266 807 code: | 808 var gradient = ctx.createLinearGradient(0, 0, 100, 0); 809 gradient.addColorStop(0, '#f00'); 810 gradient.addColorStop(1, '#f00'); 811 ctx.fillStyle = '#f00'; 812 ctx.fillRect(0, 0, 100, 50); 813 ctx.shadowColor = '#0f0'; 814 ctx.shadowOffsetY = 50; 815 ctx.fillStyle = gradient; 816 ctx.fillRect(0, -50, 100, 50); 817 818 @assert pixel 50,25 == 0,255,0,255; 819 expected: green 820 821 - name: 2d.shadow.gradient.transparent.1 822 desc: Shadows are not drawn for transparent gradient fills 823 # http://bugs.webkit.org/show_bug.cgi?id=15266 824 code: | 825 var gradient = ctx.createLinearGradient(0, 0, 100, 0); 826 gradient.addColorStop(0, 'rgba(0,0,0,0)'); 827 gradient.addColorStop(1, 'rgba(0,0,0,0)'); 828 ctx.fillStyle = '#0f0'; 829 ctx.fillRect(0, 0, 100, 50); 830 ctx.shadowColor = '#f00'; 831 ctx.shadowOffsetY = 50; 832 ctx.fillStyle = gradient; 833 ctx.fillRect(0, -50, 100, 50); 834 835 @assert pixel 50,25 == 0,255,0,255; 836 expected: green 837 838 - name: 2d.shadow.gradient.transparent.2 839 desc: Shadows are not drawn for transparent parts of gradient fills 840 # http://bugs.webkit.org/show_bug.cgi?id=15266 841 code: | 842 var gradient = ctx.createLinearGradient(0, 0, 100, 0); 843 gradient.addColorStop(0, '#f00'); 844 gradient.addColorStop(0.499, '#f00'); 845 gradient.addColorStop(0.5, 'rgba(0,0,0,0)'); 846 gradient.addColorStop(1, 'rgba(0,0,0,0)'); 847 ctx.fillStyle = '#f00'; 848 ctx.fillRect(0, 0, 50, 50); 849 ctx.fillStyle = '#0f0'; 850 ctx.fillRect(50, 0, 50, 50); 851 ctx.shadowOffsetY = 50; 852 ctx.shadowColor = '#0f0'; 853 ctx.fillStyle = gradient; 854 ctx.fillRect(0, -50, 100, 50); 855 856 @assert pixel 25,25 == 0,255,0,255; 857 @assert pixel 50,25 == 0,255,0,255; 858 @assert pixel 75,25 == 0,255,0,255; 859 expected: green 860 861 - name: 2d.shadow.gradient.alpha 862 desc: Shadows are drawn correctly for partially-transparent gradient fills 863 # http://bugs.webkit.org/show_bug.cgi?id=15266 864 code: | 865 var gradient = ctx.createLinearGradient(0, 0, 100, 0); 866 gradient.addColorStop(0, 'rgba(255,0,0,0.5)'); 867 gradient.addColorStop(1, 'rgba(255,0,0,0.5)'); 868 ctx.fillStyle = '#f00'; 869 ctx.fillRect(0, 0, 100, 50); 870 ctx.shadowOffsetY = 50; 871 ctx.shadowColor = '#00f'; 872 ctx.fillStyle = gradient; 873 ctx.fillRect(0, -50, 100, 50); 874 875 @assert pixel 50,25 ==~ 127,0,127,255; 876 expected: | 877 size 100 50 878 cr.set_source_rgb(0.5, 0, 0.5) 879 cr.rectangle(0, 0, 100, 50) 880 cr.fill() 881 882 - name: 2d.shadow.transform.1 883 desc: Shadows take account of transformations 884 code: | 885 ctx.fillStyle = '#f00'; 886 ctx.fillRect(0, 0, 100, 50); 887 ctx.shadowOffsetY = 50; 888 ctx.shadowColor = '#0f0'; 889 ctx.translate(100, 100); 890 ctx.fillRect(-100, -150, 100, 50); 891 892 @assert pixel 50,25 == 0,255,0,255; 893 expected: green 894 895 - name: 2d.shadow.transform.2 896 desc: Shadow offsets are not affected by transformations 897 code: | 898 ctx.fillStyle = '#f00'; 899 ctx.fillRect(0, 0, 100, 50); 900 ctx.shadowOffsetY = 50; 901 ctx.shadowColor = '#0f0'; 902 ctx.rotate(Math.PI) 903 ctx.fillRect(-100, 0, 100, 50); 904 905 @assert pixel 50,25 == 0,255,0,255; 906 expected: green 907 908 - name: 2d.shadow.blur.low 909 desc: Shadows look correct for small blurs 910 manual: 911 code: | 912 ctx.fillStyle = '#ff0'; 913 ctx.fillRect(0, 0, 100, 50); 914 ctx.shadowColor = '#00f'; 915 ctx.shadowOffsetY = 25; 916 for (var x = 0; x < 100; ++x) { 917 ctx.save(); 918 ctx.beginPath(); 919 ctx.rect(x, 0, 1, 50); 920 ctx.clip(); 921 ctx.shadowBlur = x; 922 ctx.fillRect(-200, -200, 500, 200); 923 ctx.restore(); 924 } 925 expected: | 926 size 100 50 927 import math 928 cr.set_source_rgb(0, 0, 1) 929 cr.rectangle(0, 0, 1, 25) 930 cr.fill() 931 cr.set_source_rgb(1, 1, 0) 932 cr.rectangle(0, 25, 1, 25) 933 cr.fill() 934 for x in range(1, 100): 935 sigma = x/2.0 936 filter = [] 937 for i in range(-24, 26): 938 filter.append(math.exp(-i*i / (2*sigma*sigma)) / (math.sqrt(2*math.pi)*sigma)) 939 accum = [0] 940 for f in filter: 941 accum.append(accum[-1] + f) 942 for y in range(0, 50): 943 cr.set_source_rgb(accum[y], accum[y], 1-accum[y]) 944 cr.rectangle(x, y, 1, 1) 945 cr.fill() 946 947 - name: 2d.shadow.blur.high 948 desc: Shadows look correct for large blurs 949 manual: 950 code: | 951 ctx.fillStyle = '#ff0'; 952 ctx.fillRect(0, 0, 100, 50); 953 ctx.shadowColor = '#00f'; 954 ctx.shadowOffsetY = 0; 955 ctx.shadowBlur = 100; 956 ctx.fillRect(-200, -200, 200, 400); 957 expected: | 958 size 100 50 959 import math 960 sigma = 100.0/2 961 filter = [] 962 for i in range(-200, 100): 963 filter.append(math.exp(-i*i / (2*sigma*sigma)) / (math.sqrt(2*math.pi)*sigma)) 964 accum = [0] 965 for f in filter: 966 accum.append(accum[-1] + f) 967 for x in range(0, 100): 968 cr.set_source_rgb(accum[x+200], accum[x+200], 1-accum[x+200]) 969 cr.rectangle(x, 0, 1, 50) 970 cr.fill() 971 972 - name: 2d.shadow.alpha.1 973 desc: Shadow color alpha components are used 974 code: | 975 ctx.fillStyle = '#0f0'; 976 ctx.fillRect(0, 0, 100, 50); 977 ctx.shadowColor = 'rgba(255, 0, 0, 0.01)'; 978 ctx.shadowOffsetY = 50; 979 ctx.fillRect(0, -50, 100, 50); 980 981 @assert pixel 50,25 ==~ 0,255,0,255 +/- 4; 982 expected: green 983 984 - name: 2d.shadow.alpha.2 985 desc: Shadow color alpha components are used 986 code: | 987 ctx.fillStyle = '#f00'; 988 ctx.fillRect(0, 0, 100, 50); 989 ctx.shadowColor = 'rgba(0, 0, 255, 0.5)'; 990 ctx.shadowOffsetY = 50; 991 ctx.fillRect(0, -50, 100, 50); 992 993 @assert pixel 50,25 ==~ 127,0,127,255; 994 expected: | 995 size 100 50 996 cr.set_source_rgb(0.5, 0, 0.5) 997 cr.rectangle(0, 0, 100, 50) 998 cr.fill() 999 1000 - name: 2d.shadow.alpha.3 1001 desc: Shadows are affected by globalAlpha 1002 code: | 1003 ctx.fillStyle = '#f00'; 1004 ctx.fillRect(0, 0, 100, 50); 1005 ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching) 1006 ctx.shadowColor = '#00f'; 1007 ctx.shadowOffsetY = 50; 1008 ctx.globalAlpha = 0.5; 1009 ctx.fillRect(0, -50, 100, 50); 1010 1011 @assert pixel 50,25 ==~ 127,0,127,255; 1012 expected: | 1013 size 100 50 1014 cr.set_source_rgb(0.5, 0, 0.5) 1015 cr.rectangle(0, 0, 100, 50) 1016 cr.fill() 1017 1018 - name: 2d.shadow.alpha.4 1019 desc: Shadows with alpha components are correctly affected by globalAlpha 1020 code: | 1021 ctx.fillStyle = '#f00'; 1022 ctx.fillRect(0, 0, 100, 50); 1023 ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching) 1024 ctx.shadowColor = 'rgba(0, 0, 255, 0.707)'; 1025 ctx.shadowOffsetY = 50; 1026 ctx.globalAlpha = 0.707; 1027 ctx.fillRect(0, -50, 100, 50); 1028 1029 @assert pixel 50,25 ==~ 127,0,127,255; 1030 expected: | 1031 size 100 50 1032 cr.set_source_rgb(0.5, 0, 0.5) 1033 cr.rectangle(0, 0, 100, 50) 1034 cr.fill() 1035 1036 - name: 2d.shadow.alpha.5 1037 desc: Shadows of shapes with alpha components are drawn correctly 1038 code: | 1039 ctx.fillStyle = '#f00'; 1040 ctx.fillRect(0, 0, 100, 50); 1041 ctx.fillStyle = 'rgba(64, 0, 0, 0.5)'; 1042 ctx.shadowColor = '#00f'; 1043 ctx.shadowOffsetY = 50; 1044 ctx.fillRect(0, -50, 100, 50); 1045 1046 @assert pixel 50,25 ==~ 127,0,127,255; 1047 expected: | 1048 size 100 50 1049 cr.set_source_rgb(0.5, 0, 0.5) 1050 cr.rectangle(0, 0, 100, 50) 1051 cr.fill() 1052 1053 - name: 2d.shadow.composite.1 1054 desc: Shadows are drawn using globalCompositeOperation 1055 code: | 1056 ctx.fillStyle = '#f00'; 1057 ctx.fillRect(0, 0, 100, 50); 1058 ctx.globalCompositeOperation = 'xor'; 1059 ctx.shadowColor = '#f00'; 1060 ctx.shadowOffsetX = 100; 1061 ctx.fillStyle = '#0f0'; 1062 ctx.fillRect(-100, 0, 200, 50); 1063 1064 @assert pixel 50,25 ==~ 0,255,0,255; 1065 expected: green 1066 1067 - name: 2d.shadow.composite.2 1068 desc: Shadows are drawn using globalCompositeOperation 1069 code: | 1070 ctx.fillStyle = '#f00'; 1071 ctx.fillRect(0, 0, 100, 50); 1072 ctx.globalCompositeOperation = 'xor'; 1073 ctx.shadowColor = '#f00'; 1074 ctx.shadowBlur = 1; 1075 ctx.fillStyle = '#0f0'; 1076 ctx.fillRect(-10, -10, 120, 70); 1077 1078 @assert pixel 50,25 ==~ 0,255,0,255; 1079 expected: green 1080 1081 - name: 2d.shadow.composite.3 1082 desc: Areas outside shadows are drawn correctly with destination-out 1083 code: | 1084 ctx.fillStyle = '#0f0'; 1085 ctx.fillRect(0, 0, 100, 50); 1086 ctx.globalCompositeOperation = 'destination-out'; 1087 ctx.shadowColor = '#f00'; 1088 ctx.shadowBlur = 10; 1089 ctx.fillStyle = '#f00'; 1090 ctx.fillRect(200, 0, 100, 50); 1091 1092 @assert pixel 5,5 ==~ 0,255,0,255; 1093 @assert pixel 50,25 ==~ 0,255,0,255; 1094 expected: green